blob: 488d3e4a2cf83bad5d1c8921da77a87282658e81 [file] [log] [blame]
Ka-Ping Yeefeb67192001-03-02 23:31:43 +00001r"""OS routines for Mac, DOS, NT, or Posix depending on what system we're on.
Guido van Rossum31104f41992-01-14 18:28:36 +00002
Guido van Rossum54f22ed2000-02-04 15:10:34 +00003This exports:
Martin v. Löwis8b10f892002-10-09 17:23:29 +00004 - all functions from posix, nt, os2, mac, or ce, e.g. unlink, stat, etc.
5 - os.path is one of the modules posixpath, ntpath, or macpath
6 - os.name is 'posix', 'nt', 'os2', 'mac', 'ce' or 'riscos'
Guido van Rossum54f22ed2000-02-04 15:10:34 +00007 - os.curdir is a string representing the current directory ('.' or ':')
8 - os.pardir is a string representing the parent directory ('..' or '::')
9 - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\')
Guido van Rossume2ae77b2001-10-24 20:42:55 +000010 - os.extsep is the extension separator ('.' or '/')
Guido van Rossum4b8c6ea2000-02-04 15:39:30 +000011 - os.altsep is the alternate pathname separator (None or '/')
Guido van Rossum54f22ed2000-02-04 15:10:34 +000012 - os.pathsep is the component separator used in $PATH etc
Guido van Rossum4b8c6ea2000-02-04 15:39:30 +000013 - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
Guido van Rossum54f22ed2000-02-04 15:10:34 +000014 - os.defpath is the default search path for executables
Guido van Rossum31104f41992-01-14 18:28:36 +000015
Guido van Rossum54f22ed2000-02-04 15:10:34 +000016Programs that import and use 'os' stand a better chance of being
17portable between different platforms. Of course, they must then
18only use functions that are defined by all platforms (e.g., unlink
19and opendir), and leave all pathname manipulation to os.path
20(e.g., split and join).
21"""
Guido van Rossum31104f41992-01-14 18:28:36 +000022
Skip Montanaro269b83b2001-02-06 01:07:02 +000023#'
24
Guido van Rossum2979b011994-08-01 11:18:30 +000025import sys
Guido van Rossuma28dab51997-08-29 22:36:47 +000026
27_names = sys.builtin_module_names
28
Tim Petersc4e09402003-04-25 07:11:48 +000029# Note: more names are added to __all__ later.
Skip Montanaro6c0a0e12001-02-28 01:00:58 +000030__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
Skip Montanaro117910d2003-02-14 19:35:31 +000031 "defpath", "name", "path"]
Skip Montanaro269b83b2001-02-06 01:07:02 +000032
33def _get_exports_list(module):
34 try:
35 return list(module.__all__)
36 except AttributeError:
37 return [n for n in dir(module) if n[0] != '_']
38
Guido van Rossuma28dab51997-08-29 22:36:47 +000039if 'posix' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000040 name = 'posix'
Guido van Rossume9387ea1998-05-22 15:26:04 +000041 linesep = '\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000042 from posix import *
43 try:
44 from posix import _exit
45 except ImportError:
46 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000047 import posixpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000048
Skip Montanaro269b83b2001-02-06 01:07:02 +000049 import posix
50 __all__.extend(_get_exports_list(posix))
51 del posix
52
Guido van Rossuma28dab51997-08-29 22:36:47 +000053elif 'nt' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000054 name = 'nt'
Guido van Rossume9387ea1998-05-22 15:26:04 +000055 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000056 from nt import *
Tim Peters6757c1e2003-01-08 21:20:57 +000057 try:
58 from nt import _exit
59 except ImportError:
60 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000061 import ntpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000062
Skip Montanaro269b83b2001-02-06 01:07:02 +000063 import nt
64 __all__.extend(_get_exports_list(nt))
65 del nt
66
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000067elif 'os2' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000068 name = 'os2'
Guido van Rossume9387ea1998-05-22 15:26:04 +000069 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000070 from os2 import *
71 try:
72 from os2 import _exit
73 except ImportError:
74 pass
Andrew MacIntyre5cef5712002-02-24 05:32:32 +000075 if sys.version.find('EMX GCC') == -1:
Skip Montanaro117910d2003-02-14 19:35:31 +000076 import ntpath as path
Andrew MacIntyre5cef5712002-02-24 05:32:32 +000077 else:
Skip Montanaro117910d2003-02-14 19:35:31 +000078 import os2emxpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000079
Skip Montanaro269b83b2001-02-06 01:07:02 +000080 import os2
81 __all__.extend(_get_exports_list(os2))
82 del os2
83
Guido van Rossuma28dab51997-08-29 22:36:47 +000084elif 'mac' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000085 name = 'mac'
Guido van Rossume9387ea1998-05-22 15:26:04 +000086 linesep = '\r'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000087 from mac import *
88 try:
89 from mac import _exit
90 except ImportError:
91 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000092 import macpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000093
Skip Montanaro269b83b2001-02-06 01:07:02 +000094 import mac
95 __all__.extend(_get_exports_list(mac))
96 del mac
97
Guido van Rossum18df5d41999-06-11 01:37:27 +000098elif 'ce' in _names:
99 name = 'ce'
100 linesep = '\r\n'
Guido van Rossum18df5d41999-06-11 01:37:27 +0000101 from ce import *
Tim Peters6757c1e2003-01-08 21:20:57 +0000102 try:
103 from ce import _exit
104 except ImportError:
105 pass
Guido van Rossum18df5d41999-06-11 01:37:27 +0000106 # We can use the standard Windows path.
Skip Montanaro117910d2003-02-14 19:35:31 +0000107 import ntpath as path
Tim Petersf2715e02003-02-19 02:35:07 +0000108
Skip Montanaro269b83b2001-02-06 01:07:02 +0000109 import ce
110 __all__.extend(_get_exports_list(ce))
111 del ce
112
Guido van Rossumd74fb6b2001-03-02 06:43:49 +0000113elif 'riscos' in _names:
114 name = 'riscos'
115 linesep = '\n'
Guido van Rossumd74fb6b2001-03-02 06:43:49 +0000116 from riscos import *
117 try:
118 from riscos import _exit
119 except ImportError:
120 pass
Skip Montanaro117910d2003-02-14 19:35:31 +0000121 import riscospath as path
Tim Petersf2715e02003-02-19 02:35:07 +0000122
Guido van Rossumd74fb6b2001-03-02 06:43:49 +0000123 import riscos
124 __all__.extend(_get_exports_list(riscos))
Skip Montanaro81e4b1c2001-03-06 15:26:07 +0000125 del riscos
Guido van Rossumd74fb6b2001-03-02 06:43:49 +0000126
Guido van Rossum2979b011994-08-01 11:18:30 +0000127else:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000128 raise ImportError, 'no os specific module found'
Guido van Rossume65cce51993-11-08 15:05:21 +0000129
Skip Montanaro117910d2003-02-14 19:35:31 +0000130sys.modules['os.path'] = path
131from os.path import curdir, pardir, sep, pathsep, defpath, extsep, altsep
Skip Montanaro269b83b2001-02-06 01:07:02 +0000132
Guido van Rossuma28dab51997-08-29 22:36:47 +0000133del _names
134
Skip Montanaro269b83b2001-02-06 01:07:02 +0000135#'
136
Guido van Rossum4def7de1998-07-24 20:48:03 +0000137# Super directory utilities.
138# (Inspired by Eric Raymond; the doc strings are mostly his)
139
140def makedirs(name, mode=0777):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000141 """makedirs(path [, mode=0777])
Guido van Rossum4def7de1998-07-24 20:48:03 +0000142
143 Super-mkdir; create a leaf directory and all intermediate ones.
144 Works like mkdir, except that any intermediate path segment (not
145 just the rightmost) will be created if it does not exist. This is
146 recursive.
147
148 """
149 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000150 if not tail:
151 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000152 if head and tail and not path.exists(head):
153 makedirs(head, mode)
154 mkdir(name, mode)
155
156def removedirs(name):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000157 """removedirs(path)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000158
159 Super-rmdir; remove a leaf directory and empty all intermediate
160 ones. Works like rmdir except that, if the leaf directory is
161 successfully removed, directories corresponding to rightmost path
Tim Petersc4e09402003-04-25 07:11:48 +0000162 segments will be pruned away until either the whole path is
Guido van Rossum4def7de1998-07-24 20:48:03 +0000163 consumed or an error occurs. Errors during this latter phase are
164 ignored -- they generally mean that a directory was not empty.
165
166 """
167 rmdir(name)
168 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000169 if not tail:
170 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000171 while head and tail:
172 try:
173 rmdir(head)
174 except error:
175 break
176 head, tail = path.split(head)
177
178def renames(old, new):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000179 """renames(old, new)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000180
181 Super-rename; create directories as necessary and delete any left
182 empty. Works like rename, except creation of any intermediate
183 directories needed to make the new pathname good is attempted
184 first. After the rename, directories corresponding to rightmost
185 path segments of the old name will be pruned way until either the
186 whole path is consumed or a nonempty directory is found.
187
188 Note: this function can fail with the new directory structure made
189 if you lack permissions needed to unlink the leaf directory or
190 file.
191
192 """
193 head, tail = path.split(new)
194 if head and tail and not path.exists(head):
195 makedirs(head)
196 rename(old, new)
197 head, tail = path.split(old)
198 if head and tail:
199 try:
200 removedirs(head)
201 except error:
202 pass
203
Skip Montanaro269b83b2001-02-06 01:07:02 +0000204__all__.extend(["makedirs", "removedirs", "renames"])
205
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000206def walk(top, topdown=True, onerror=None):
Tim Petersc4e09402003-04-25 07:11:48 +0000207 """Directory tree generator.
208
209 For each directory in the directory tree rooted at top (including top
210 itself, but excluding '.' and '..'), yields a 3-tuple
211
212 dirpath, dirnames, filenames
213
214 dirpath is a string, the path to the directory. dirnames is a list of
215 the names of the subdirectories in dirpath (excluding '.' and '..').
216 filenames is a list of the names of the non-directory files in dirpath.
217 Note that the names in the lists are just names, with no path components.
218 To get a full path (which begins with top) to a file or directory in
219 dirpath, do os.path.join(dirpath, name).
220
221 If optional arg 'topdown' is true or not specified, the triple for a
222 directory is generated before the triples for any of its subdirectories
223 (directories are generated top down). If topdown is false, the triple
224 for a directory is generated after the triples for all of its
225 subdirectories (directories are generated bottom up).
226
227 When topdown is true, the caller can modify the dirnames list in-place
228 (e.g., via del or slice assignment), and walk will only recurse into the
229 subdirectories whose names remain in dirnames; this can be used to prune
230 the search, or to impose a specific order of visiting. Modifying
231 dirnames when topdown is false is ineffective, since the directories in
232 dirnames have already been generated by the time dirnames itself is
233 generated.
234
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000235 By default errors from the os.listdir() call are ignored. If
236 optional arg 'onerror' is specified, it should be a function; it
237 will be called with one argument, an os.error instance. It can
238 report the error to continue with the walk, or raise the exception
239 to abort the walk. Note that the filename is available as the
240 filename attribute of the exception object.
241
Tim Petersc4e09402003-04-25 07:11:48 +0000242 Caution: if you pass a relative pathname for top, don't change the
243 current working directory between resumptions of walk. walk never
244 changes the current directory, and assumes that the client doesn't
245 either.
246
247 Example:
248
249 from os.path import join, getsize
250 for root, dirs, files in walk('python/Lib/email'):
251 print root, "consumes",
252 print sum([getsize(join(root, name)) for name in files]),
253 print "bytes in", len(files), "non-directory files"
254 if 'CVS' in dirs:
255 dirs.remove('CVS') # don't visit CVS directories
256 """
257
258 from os.path import join, isdir, islink
259
260 # We may not have read permission for top, in which case we can't
261 # get a list of the files the directory contains. os.path.walk
262 # always suppressed the exception then, rather than blow up for a
263 # minor reason when (say) a thousand readable directories are still
264 # left to visit. That logic is copied here.
265 try:
266 # Note that listdir and error are globals in this module due
267 # to earlier import-*.
268 names = listdir(top)
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000269 except error, err:
270 if onerror is not None:
271 onerror(err)
Tim Petersc4e09402003-04-25 07:11:48 +0000272 return
273
274 dirs, nondirs = [], []
275 for name in names:
276 if isdir(join(top, name)):
277 dirs.append(name)
278 else:
279 nondirs.append(name)
280
281 if topdown:
282 yield top, dirs, nondirs
283 for name in dirs:
284 path = join(top, name)
285 if not islink(path):
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000286 for x in walk(path, topdown, onerror):
Tim Petersc4e09402003-04-25 07:11:48 +0000287 yield x
288 if not topdown:
289 yield top, dirs, nondirs
290
291__all__.append("walk")
292
Guido van Rossuma28dab51997-08-29 22:36:47 +0000293# Make sure os.environ exists, at least
294try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000295 environ
Guido van Rossuma28dab51997-08-29 22:36:47 +0000296except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000297 environ = {}
Guido van Rossuma28dab51997-08-29 22:36:47 +0000298
Guido van Rossume65cce51993-11-08 15:05:21 +0000299def execl(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000300 """execl(file, *args)
301
302 Execute the executable file with argument list args, replacing the
303 current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000304 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000305
306def execle(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000307 """execle(file, *args, env)
308
309 Execute the executable file with argument list args and
310 environment env, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000311 env = args[-1]
312 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000313
314def execlp(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000315 """execlp(file, *args)
316
317 Execute the executable file (which is searched for along $PATH)
318 with argument list args, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000319 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000320
Guido van Rossum030afb11995-03-14 17:27:18 +0000321def execlpe(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000322 """execlpe(file, *args, env)
323
324 Execute the executable file (which is searched for along $PATH)
325 with argument list args and environment env, replacing the current
Tim Peters2344fae2001-01-15 00:50:52 +0000326 process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000327 env = args[-1]
328 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000329
Guido van Rossume65cce51993-11-08 15:05:21 +0000330def execvp(file, args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000331 """execp(file, args)
332
333 Execute the executable file (which is searched for along $PATH)
334 with argument list args, replacing the current process.
Thomas Wouters7e474022000-07-16 12:04:32 +0000335 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000336 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000337
338def execvpe(file, args, env):
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000339 """execvpe(file, args, env)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000340
341 Execute the executable file (which is searched for along $PATH)
342 with argument list args and environment env , replacing the
343 current process.
Tim Peters2344fae2001-01-15 00:50:52 +0000344 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000345 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000346
Skip Montanaro269b83b2001-02-06 01:07:02 +0000347__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
348
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000349def _execvpe(file, args, env=None):
Guido van Rossumaed51d82002-08-05 16:13:24 +0000350 from errno import ENOENT, ENOTDIR
351
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000352 if env is not None:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000353 func = execve
354 argrest = (args, env)
355 else:
356 func = execv
357 argrest = (args,)
358 env = environ
Guido van Rossumaed51d82002-08-05 16:13:24 +0000359
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000360 head, tail = path.split(file)
361 if head:
Guido van Rossum68468eb2003-02-27 20:14:51 +0000362 func(file, *argrest)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000363 return
Raymond Hettinger54f02222002-06-01 14:18:47 +0000364 if 'PATH' in env:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000365 envpath = env['PATH']
366 else:
367 envpath = defpath
Guido van Rossum965fdae2000-04-04 19:50:04 +0000368 PATH = envpath.split(pathsep)
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000369 saved_exc = None
370 saved_tb = None
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000371 for dir in PATH:
372 fullname = path.join(dir, file)
373 try:
Guido van Rossum68468eb2003-02-27 20:14:51 +0000374 func(fullname, *argrest)
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000375 except error, e:
376 tb = sys.exc_info()[2]
377 if (e.errno != ENOENT and e.errno != ENOTDIR
378 and saved_exc is None):
379 saved_exc = e
380 saved_tb = tb
381 if saved_exc:
382 raise error, saved_exc, saved_tb
383 raise error, e, tb
Guido van Rossumd74fb6b2001-03-02 06:43:49 +0000384
Martin v. Löwisa90f4382001-03-07 09:05:45 +0000385# Change environ to automatically call putenv() if it exists
386try:
387 # This will fail if there's no putenv
388 putenv
389except NameError:
390 pass
391else:
392 import UserDict
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000393
Guido van Rossumc524d952001-10-19 01:31:59 +0000394 # Fake unsetenv() for Windows
Martin v. Löwis8b10f892002-10-09 17:23:29 +0000395 # not sure about os2 here but
Guido van Rossumc524d952001-10-19 01:31:59 +0000396 # I'm guessing they are the same.
397
Martin v. Löwis8b10f892002-10-09 17:23:29 +0000398 if name in ('os2', 'nt'):
Guido van Rossumc524d952001-10-19 01:31:59 +0000399 def unsetenv(key):
400 putenv(key, "")
401
Martin v. Löwisa90f4382001-03-07 09:05:45 +0000402 if name == "riscos":
403 # On RISC OS, all env access goes through getenv and putenv
404 from riscosenviron import _Environ
Martin v. Löwis8b10f892002-10-09 17:23:29 +0000405 elif name in ('os2', 'nt'): # Where Env Var Names Must Be UPPERCASE
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000406 # But we store them as upper case
Raymond Hettingerca2f5372002-09-06 19:36:31 +0000407 class _Environ(UserDict.IterableUserDict):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000408 def __init__(self, environ):
409 UserDict.UserDict.__init__(self)
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000410 data = self.data
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000411 for k, v in environ.items():
Guido van Rossum965fdae2000-04-04 19:50:04 +0000412 data[k.upper()] = v
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000413 def __setitem__(self, key, item):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000414 putenv(key, item)
Guido van Rossum965fdae2000-04-04 19:50:04 +0000415 self.data[key.upper()] = item
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000416 def __getitem__(self, key):
Guido van Rossum965fdae2000-04-04 19:50:04 +0000417 return self.data[key.upper()]
Guido van Rossumc524d952001-10-19 01:31:59 +0000418 try:
419 unsetenv
420 except NameError:
421 def __delitem__(self, key):
422 del self.data[key.upper()]
423 else:
424 def __delitem__(self, key):
425 unsetenv(key)
426 del self.data[key.upper()]
Guido van Rossumb46413f1999-05-03 15:23:24 +0000427 def has_key(self, key):
Raymond Hettinger54f02222002-06-01 14:18:47 +0000428 return key.upper() in self.data
429 def __contains__(self, key):
430 return key.upper() in self.data
Guido van Rossum965fdae2000-04-04 19:50:04 +0000431 def get(self, key, failobj=None):
432 return self.data.get(key.upper(), failobj)
433 def update(self, dict):
434 for k, v in dict.items():
435 self[k] = v
Martin v. Löwisa066f462002-05-02 17:39:19 +0000436 def copy(self):
437 return dict(self)
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000438
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000439 else: # Where Env Var Names Can Be Mixed Case
Raymond Hettinger05212fc2002-09-07 04:48:03 +0000440 class _Environ(UserDict.IterableUserDict):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000441 def __init__(self, environ):
442 UserDict.UserDict.__init__(self)
443 self.data = environ
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000444 def __setitem__(self, key, item):
445 putenv(key, item)
446 self.data[key] = item
Guido van Rossum965fdae2000-04-04 19:50:04 +0000447 def update(self, dict):
448 for k, v in dict.items():
449 self[k] = v
Guido van Rossumc524d952001-10-19 01:31:59 +0000450 try:
451 unsetenv
452 except NameError:
453 pass
454 else:
455 def __delitem__(self, key):
456 unsetenv(key)
457 del self.data[key]
Martin v. Löwisa066f462002-05-02 17:39:19 +0000458 def copy(self):
459 return dict(self)
Tim Peters1633a2e2001-10-30 05:56:40 +0000460
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000461
462 environ = _Environ(environ)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000463
Jack Jansenb11ce9b2003-01-08 16:33:40 +0000464def getenv(key, default=None):
Tim Peters2c60f7a2003-01-29 03:49:43 +0000465 """Get an environment variable, return None if it doesn't exist.
466 The optional second argument can specify an alternate default."""
467 return environ.get(key, default)
Jack Jansenb11ce9b2003-01-08 16:33:40 +0000468__all__.append("getenv")
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000469
470def _exists(name):
471 try:
472 eval(name)
Tim Petersbc0e9102002-04-04 22:55:58 +0000473 return True
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000474 except NameError:
Tim Petersbc0e9102002-04-04 22:55:58 +0000475 return False
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000476
477# Supply spawn*() (probably only for Unix)
478if _exists("fork") and not _exists("spawnv") and _exists("execv"):
479
480 P_WAIT = 0
481 P_NOWAIT = P_NOWAITO = 1
482
483 # XXX Should we support P_DETACH? I suppose it could fork()**2
484 # and close the std I/O streams. Also, P_OVERLAY is the same
485 # as execv*()?
486
487 def _spawnvef(mode, file, args, env, func):
488 # Internal helper; func is the exec*() function to use
489 pid = fork()
490 if not pid:
491 # Child
492 try:
493 if env is None:
494 func(file, args)
495 else:
496 func(file, args, env)
497 except:
498 _exit(127)
499 else:
500 # Parent
501 if mode == P_NOWAIT:
502 return pid # Caller is responsible for waiting!
503 while 1:
504 wpid, sts = waitpid(pid, 0)
505 if WIFSTOPPED(sts):
506 continue
507 elif WIFSIGNALED(sts):
508 return -WTERMSIG(sts)
509 elif WIFEXITED(sts):
510 return WEXITSTATUS(sts)
511 else:
512 raise error, "Not stopped, signaled or exited???"
513
514 def spawnv(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000515 """spawnv(mode, file, args) -> integer
516
517Execute file with arguments from args in a subprocess.
518If mode == P_NOWAIT return the pid of the process.
519If mode == P_WAIT return the process's exit code if it exits normally;
Tim Peters2344fae2001-01-15 00:50:52 +0000520otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000521 return _spawnvef(mode, file, args, None, execv)
522
523 def spawnve(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000524 """spawnve(mode, file, args, env) -> integer
525
526Execute file with arguments from args in a subprocess with the
527specified environment.
528If mode == P_NOWAIT return the pid of the process.
529If mode == P_WAIT return the process's exit code if it exits normally;
530otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000531 return _spawnvef(mode, file, args, env, execve)
532
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000533 # Note: spawnvp[e] is't currently supported on Windows
534
535 def spawnvp(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000536 """spawnvp(mode, file, args) -> integer
537
538Execute file (which is looked for along $PATH) with arguments from
539args in a subprocess.
540If mode == P_NOWAIT return the pid of the process.
541If mode == P_WAIT return the process's exit code if it exits normally;
542otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000543 return _spawnvef(mode, file, args, None, execvp)
544
545 def spawnvpe(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000546 """spawnvpe(mode, file, args, env) -> integer
547
548Execute file (which is looked for along $PATH) with arguments from
549args in a subprocess with the supplied environment.
550If mode == P_NOWAIT return the pid of the process.
551If mode == P_WAIT return the process's exit code if it exits normally;
552otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000553 return _spawnvef(mode, file, args, env, execvpe)
554
555if _exists("spawnv"):
556 # These aren't supplied by the basic Windows code
557 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000558
559 def spawnl(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000560 """spawnl(mode, file, *args) -> integer
561
562Execute file with arguments from args in a subprocess.
563If mode == P_NOWAIT return the pid of the process.
564If mode == P_WAIT return the process's exit code if it exits normally;
565otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000566 return spawnv(mode, file, args)
567
568 def spawnle(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000569 """spawnle(mode, file, *args, env) -> integer
570
571Execute file with arguments from args in a subprocess with the
572supplied environment.
573If mode == P_NOWAIT return the pid of the process.
574If mode == P_WAIT return the process's exit code if it exits normally;
575otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000576 env = args[-1]
577 return spawnve(mode, file, args[:-1], env)
578
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000579if _exists("spawnvp"):
580 # At the moment, Windows doesn't implement spawnvp[e],
581 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000582 def spawnlp(mode, file, *args):
Neal Norwitzb7f68102003-07-02 02:49:33 +0000583 """spawnlp(mode, file, *args) -> integer
Guido van Rossume0cd2912000-04-21 18:35:36 +0000584
585Execute file (which is looked for along $PATH) with arguments from
586args in a subprocess with the supplied environment.
587If mode == P_NOWAIT return the pid of the process.
588If mode == P_WAIT return the process's exit code if it exits normally;
589otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000590 return spawnvp(mode, file, args)
591
592 def spawnlpe(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000593 """spawnlpe(mode, file, *args, env) -> integer
594
595Execute file (which is looked for along $PATH) with arguments from
596args in a subprocess with the supplied environment.
597If mode == P_NOWAIT return the pid of the process.
598If mode == P_WAIT return the process's exit code if it exits normally;
599otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000600 env = args[-1]
601 return spawnvpe(mode, file, args[:-1], env)
Guido van Rossume0cd2912000-04-21 18:35:36 +0000602
603
Skip Montanaro269b83b2001-02-06 01:07:02 +0000604 __all__.extend(["spawnlp","spawnlpe","spawnv", "spawnve","spawnvp",
605 "spawnvpe","spawnl","spawnle",])
606
607
Guido van Rossumd9a8e962000-09-19 03:04:52 +0000608# Supply popen2 etc. (for Unix)
609if _exists("fork"):
610 if not _exists("popen2"):
611 def popen2(cmd, mode="t", bufsize=-1):
Guido van Rossumd9a8e962000-09-19 03:04:52 +0000612 import popen2
613 stdout, stdin = popen2.popen2(cmd, bufsize)
614 return stdin, stdout
Skip Montanaro269b83b2001-02-06 01:07:02 +0000615 __all__.append("popen2")
Fred Drake31f182e2000-08-28 17:20:05 +0000616
Guido van Rossumd9a8e962000-09-19 03:04:52 +0000617 if not _exists("popen3"):
618 def popen3(cmd, mode="t", bufsize=-1):
Guido van Rossumd9a8e962000-09-19 03:04:52 +0000619 import popen2
620 stdout, stdin, stderr = popen2.popen3(cmd, bufsize)
621 return stdin, stdout, stderr
Skip Montanaro269b83b2001-02-06 01:07:02 +0000622 __all__.append("popen3")
Fred Drake20af3172000-09-28 19:10:56 +0000623
624 if not _exists("popen4"):
625 def popen4(cmd, mode="t", bufsize=-1):
626 import popen2
627 stdout, stdin = popen2.popen4(cmd, bufsize)
628 return stdin, stdout
Skip Montanaro269b83b2001-02-06 01:07:02 +0000629 __all__.append("popen4")
Michael W. Hudson0e025302002-03-06 17:11:18 +0000630
631import copy_reg as _copy_reg
632
633def _make_stat_result(tup, dict):
634 return stat_result(tup, dict)
635
636def _pickle_stat_result(sr):
637 (type, args) = sr.__reduce__()
638 return (_make_stat_result, args)
639
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000640try:
641 _copy_reg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
642except NameError: # stat_result may not exist
643 pass
Michael W. Hudson0e025302002-03-06 17:11:18 +0000644
645def _make_statvfs_result(tup, dict):
646 return statvfs_result(tup, dict)
647
648def _pickle_statvfs_result(sr):
649 (type, args) = sr.__reduce__()
650 return (_make_statvfs_result, args)
651
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000652try:
653 _copy_reg.pickle(statvfs_result, _pickle_statvfs_result,
654 _make_statvfs_result)
Michael W. Hudsone5363b72002-03-15 10:21:59 +0000655except NameError: # statvfs_result may not exist
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000656 pass