blob: b8d7a0f828a6a0611059854a60b6c9d764db0fc5 [file] [log] [blame]
Georg Brandlbde4ad42006-01-20 21:36:02 +00001r"""OS routines for Mac, 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
Skip Montanaro289bc052007-08-17 02:30:27 +00006 - os.name is 'posix', 'nt', 'os2', 'mac' or 'ce'
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 Rossum4b8c6ea2000-02-04 15:39:30 +000010 - os.altsep is the alternate pathname separator (None or '/')
Guido van Rossum54f22ed2000-02-04 15:10:34 +000011 - os.pathsep is the component separator used in $PATH etc
Guido van Rossum4b8c6ea2000-02-04 15:39:30 +000012 - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
Guido van Rossum54f22ed2000-02-04 15:10:34 +000013 - os.defpath is the default search path for executables
Martin v. Löwisbdec50f2004-06-08 08:29:33 +000014 - os.devnull is the file path of the null device ('/dev/null', etc.)
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",
Martin v. Löwis22b457e2005-01-16 08:40:58 +000031 "defpath", "name", "path", "devnull",
32 "SEEK_SET", "SEEK_CUR", "SEEK_END"]
Skip Montanaro269b83b2001-02-06 01:07:02 +000033
34def _get_exports_list(module):
35 try:
36 return list(module.__all__)
37 except AttributeError:
38 return [n for n in dir(module) if n[0] != '_']
39
Guido van Rossuma28dab51997-08-29 22:36:47 +000040if 'posix' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000041 name = 'posix'
Guido van Rossume9387ea1998-05-22 15:26:04 +000042 linesep = '\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000043 from posix import *
44 try:
45 from posix import _exit
46 except ImportError:
47 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000048 import posixpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000049
Skip Montanaro269b83b2001-02-06 01:07:02 +000050 import posix
51 __all__.extend(_get_exports_list(posix))
52 del posix
53
Guido van Rossuma28dab51997-08-29 22:36:47 +000054elif 'nt' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000055 name = 'nt'
Guido van Rossume9387ea1998-05-22 15:26:04 +000056 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000057 from nt import *
Tim Peters6757c1e2003-01-08 21:20:57 +000058 try:
59 from nt import _exit
60 except ImportError:
61 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000062 import ntpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000063
Skip Montanaro269b83b2001-02-06 01:07:02 +000064 import nt
65 __all__.extend(_get_exports_list(nt))
66 del nt
67
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000068elif 'os2' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000069 name = 'os2'
Guido van Rossume9387ea1998-05-22 15:26:04 +000070 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000071 from os2 import *
72 try:
73 from os2 import _exit
74 except ImportError:
75 pass
Andrew MacIntyre5cef5712002-02-24 05:32:32 +000076 if sys.version.find('EMX GCC') == -1:
Skip Montanaro117910d2003-02-14 19:35:31 +000077 import ntpath as path
Andrew MacIntyre5cef5712002-02-24 05:32:32 +000078 else:
Skip Montanaro117910d2003-02-14 19:35:31 +000079 import os2emxpath as path
Andrew MacIntyre89f98652003-12-02 12:33:01 +000080 from _emx_link import link
Tim Petersf2715e02003-02-19 02:35:07 +000081
Skip Montanaro269b83b2001-02-06 01:07:02 +000082 import os2
83 __all__.extend(_get_exports_list(os2))
84 del os2
85
Guido van Rossuma28dab51997-08-29 22:36:47 +000086elif 'mac' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000087 name = 'mac'
Guido van Rossume9387ea1998-05-22 15:26:04 +000088 linesep = '\r'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000089 from mac import *
90 try:
91 from mac import _exit
92 except ImportError:
93 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000094 import macpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000095
Skip Montanaro269b83b2001-02-06 01:07:02 +000096 import mac
97 __all__.extend(_get_exports_list(mac))
98 del mac
99
Guido van Rossum18df5d41999-06-11 01:37:27 +0000100elif 'ce' in _names:
101 name = 'ce'
102 linesep = '\r\n'
Guido van Rossum18df5d41999-06-11 01:37:27 +0000103 from ce import *
Tim Peters6757c1e2003-01-08 21:20:57 +0000104 try:
105 from ce import _exit
106 except ImportError:
107 pass
Guido van Rossum18df5d41999-06-11 01:37:27 +0000108 # We can use the standard Windows path.
Skip Montanaro117910d2003-02-14 19:35:31 +0000109 import ntpath as path
Tim Petersf2715e02003-02-19 02:35:07 +0000110
Skip Montanaro269b83b2001-02-06 01:07:02 +0000111 import ce
112 __all__.extend(_get_exports_list(ce))
113 del ce
114
Guido van Rossum2979b011994-08-01 11:18:30 +0000115else:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000116 raise ImportError, 'no os specific module found'
Guido van Rossume65cce51993-11-08 15:05:21 +0000117
Skip Montanaro117910d2003-02-14 19:35:31 +0000118sys.modules['os.path'] = path
Skip Montanaro7a98be22007-08-16 14:35:24 +0000119from os.path import curdir, pardir, sep, pathsep, defpath, altsep, devnull
Skip Montanaro269b83b2001-02-06 01:07:02 +0000120
Guido van Rossuma28dab51997-08-29 22:36:47 +0000121del _names
122
Martin v. Löwis22b457e2005-01-16 08:40:58 +0000123# Python uses fixed values for the SEEK_ constants; they are mapped
124# to native constants if necessary in posixmodule.c
125SEEK_SET = 0
126SEEK_CUR = 1
127SEEK_END = 2
128
Skip Montanaro269b83b2001-02-06 01:07:02 +0000129#'
130
Guido van Rossum4def7de1998-07-24 20:48:03 +0000131# Super directory utilities.
132# (Inspired by Eric Raymond; the doc strings are mostly his)
133
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000134def makedirs(name, mode=0o777):
135 """makedirs(path [, mode=0o777])
Guido van Rossum4def7de1998-07-24 20:48:03 +0000136
137 Super-mkdir; create a leaf directory and all intermediate ones.
138 Works like mkdir, except that any intermediate path segment (not
139 just the rightmost) will be created if it does not exist. This is
140 recursive.
141
142 """
Thomas Wouters89f507f2006-12-13 04:49:30 +0000143 from errno import EEXIST
Guido van Rossum4def7de1998-07-24 20:48:03 +0000144 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000145 if not tail:
146 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000147 if head and tail and not path.exists(head):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000148 try:
149 makedirs(head, mode)
Guido van Rossumb940e112007-01-10 16:19:56 +0000150 except OSError as e:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000151 # be happy if someone already created the path
152 if e.errno != EEXIST:
153 raise
Andrew M. Kuchling6fccc8a2003-12-23 16:33:28 +0000154 if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists
155 return
Guido van Rossum4def7de1998-07-24 20:48:03 +0000156 mkdir(name, mode)
157
158def removedirs(name):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000159 """removedirs(path)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000160
Fredrik Lundh96c1c7a2005-11-12 15:55:04 +0000161 Super-rmdir; remove a leaf directory and all empty intermediate
Guido van Rossum4def7de1998-07-24 20:48:03 +0000162 ones. Works like rmdir except that, if the leaf directory is
163 successfully removed, directories corresponding to rightmost path
Tim Petersc4e09402003-04-25 07:11:48 +0000164 segments will be pruned away until either the whole path is
Guido van Rossum4def7de1998-07-24 20:48:03 +0000165 consumed or an error occurs. Errors during this latter phase are
166 ignored -- they generally mean that a directory was not empty.
167
168 """
169 rmdir(name)
170 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000171 if not tail:
172 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000173 while head and tail:
174 try:
175 rmdir(head)
176 except error:
177 break
178 head, tail = path.split(head)
179
180def renames(old, new):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000181 """renames(old, new)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000182
183 Super-rename; create directories as necessary and delete any left
184 empty. Works like rename, except creation of any intermediate
185 directories needed to make the new pathname good is attempted
186 first. After the rename, directories corresponding to rightmost
187 path segments of the old name will be pruned way until either the
188 whole path is consumed or a nonempty directory is found.
189
190 Note: this function can fail with the new directory structure made
191 if you lack permissions needed to unlink the leaf directory or
192 file.
193
194 """
195 head, tail = path.split(new)
196 if head and tail and not path.exists(head):
197 makedirs(head)
198 rename(old, new)
199 head, tail = path.split(old)
200 if head and tail:
201 try:
202 removedirs(head)
203 except error:
204 pass
205
Skip Montanaro269b83b2001-02-06 01:07:02 +0000206__all__.extend(["makedirs", "removedirs", "renames"])
207
Guido van Rossumd8faa362007-04-27 19:54:29 +0000208def walk(top, topdown=True, onerror=None, followlinks=False):
Tim Petersc4e09402003-04-25 07:11:48 +0000209 """Directory tree generator.
210
211 For each directory in the directory tree rooted at top (including top
212 itself, but excluding '.' and '..'), yields a 3-tuple
213
214 dirpath, dirnames, filenames
215
216 dirpath is a string, the path to the directory. dirnames is a list of
217 the names of the subdirectories in dirpath (excluding '.' and '..').
218 filenames is a list of the names of the non-directory files in dirpath.
219 Note that the names in the lists are just names, with no path components.
220 To get a full path (which begins with top) to a file or directory in
221 dirpath, do os.path.join(dirpath, name).
222
223 If optional arg 'topdown' is true or not specified, the triple for a
224 directory is generated before the triples for any of its subdirectories
225 (directories are generated top down). If topdown is false, the triple
226 for a directory is generated after the triples for all of its
227 subdirectories (directories are generated bottom up).
228
229 When topdown is true, the caller can modify the dirnames list in-place
230 (e.g., via del or slice assignment), and walk will only recurse into the
231 subdirectories whose names remain in dirnames; this can be used to prune
232 the search, or to impose a specific order of visiting. Modifying
233 dirnames when topdown is false is ineffective, since the directories in
234 dirnames have already been generated by the time dirnames itself is
235 generated.
236
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000237 By default errors from the os.listdir() call are ignored. If
238 optional arg 'onerror' is specified, it should be a function; it
239 will be called with one argument, an os.error instance. It can
240 report the error to continue with the walk, or raise the exception
241 to abort the walk. Note that the filename is available as the
242 filename attribute of the exception object.
243
Guido van Rossumd8faa362007-04-27 19:54:29 +0000244 By default, os.walk does not follow symbolic links to subdirectories on
245 systems that support them. In order to get this functionality, set the
246 optional argument 'followlinks' to true.
247
Tim Petersc4e09402003-04-25 07:11:48 +0000248 Caution: if you pass a relative pathname for top, don't change the
249 current working directory between resumptions of walk. walk never
250 changes the current directory, and assumes that the client doesn't
251 either.
252
253 Example:
254
255 from os.path import join, getsize
256 for root, dirs, files in walk('python/Lib/email'):
257 print root, "consumes",
258 print sum([getsize(join(root, name)) for name in files]),
259 print "bytes in", len(files), "non-directory files"
260 if 'CVS' in dirs:
261 dirs.remove('CVS') # don't visit CVS directories
262 """
263
264 from os.path import join, isdir, islink
265
266 # We may not have read permission for top, in which case we can't
267 # get a list of the files the directory contains. os.path.walk
268 # always suppressed the exception then, rather than blow up for a
269 # minor reason when (say) a thousand readable directories are still
270 # left to visit. That logic is copied here.
271 try:
272 # Note that listdir and error are globals in this module due
273 # to earlier import-*.
274 names = listdir(top)
Guido van Rossumb940e112007-01-10 16:19:56 +0000275 except error as err:
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000276 if onerror is not None:
277 onerror(err)
Tim Petersc4e09402003-04-25 07:11:48 +0000278 return
279
280 dirs, nondirs = [], []
281 for name in names:
282 if isdir(join(top, name)):
283 dirs.append(name)
284 else:
285 nondirs.append(name)
286
287 if topdown:
288 yield top, dirs, nondirs
289 for name in dirs:
290 path = join(top, name)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000291 if followlinks or not islink(path):
292 for x in walk(path, topdown, onerror, followlinks):
Tim Petersc4e09402003-04-25 07:11:48 +0000293 yield x
294 if not topdown:
295 yield top, dirs, nondirs
296
297__all__.append("walk")
298
Guido van Rossuma28dab51997-08-29 22:36:47 +0000299# Make sure os.environ exists, at least
300try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000301 environ
Guido van Rossuma28dab51997-08-29 22:36:47 +0000302except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000303 environ = {}
Guido van Rossuma28dab51997-08-29 22:36:47 +0000304
Guido van Rossume65cce51993-11-08 15:05:21 +0000305def execl(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000306 """execl(file, *args)
307
308 Execute the executable file with argument list args, replacing the
309 current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000310 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000311
312def execle(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000313 """execle(file, *args, env)
314
315 Execute the executable file with argument list args and
316 environment env, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000317 env = args[-1]
318 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000319
320def execlp(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000321 """execlp(file, *args)
322
323 Execute the executable file (which is searched for along $PATH)
324 with argument list args, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000325 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000326
Guido van Rossum030afb11995-03-14 17:27:18 +0000327def execlpe(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000328 """execlpe(file, *args, env)
329
330 Execute the executable file (which is searched for along $PATH)
331 with argument list args and environment env, replacing the current
Tim Peters2344fae2001-01-15 00:50:52 +0000332 process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000333 env = args[-1]
334 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000335
Guido van Rossume65cce51993-11-08 15:05:21 +0000336def execvp(file, args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000337 """execp(file, args)
338
339 Execute the executable file (which is searched for along $PATH)
340 with argument list args, replacing the current process.
Thomas Wouters7e474022000-07-16 12:04:32 +0000341 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000342 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000343
344def execvpe(file, args, env):
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000345 """execvpe(file, args, env)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000346
347 Execute the executable file (which is searched for along $PATH)
348 with argument list args and environment env , replacing the
349 current process.
Tim Peters2344fae2001-01-15 00:50:52 +0000350 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000351 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000352
Skip Montanaro269b83b2001-02-06 01:07:02 +0000353__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
354
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000355def _execvpe(file, args, env=None):
Guido van Rossumaed51d82002-08-05 16:13:24 +0000356 from errno import ENOENT, ENOTDIR
357
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000358 if env is not None:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000359 func = execve
360 argrest = (args, env)
361 else:
362 func = execv
363 argrest = (args,)
364 env = environ
Guido van Rossumaed51d82002-08-05 16:13:24 +0000365
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000366 head, tail = path.split(file)
367 if head:
Guido van Rossum68468eb2003-02-27 20:14:51 +0000368 func(file, *argrest)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000369 return
Raymond Hettinger54f02222002-06-01 14:18:47 +0000370 if 'PATH' in env:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000371 envpath = env['PATH']
372 else:
373 envpath = defpath
Guido van Rossum965fdae2000-04-04 19:50:04 +0000374 PATH = envpath.split(pathsep)
Guido van Rossume7ba4952007-06-06 23:52:48 +0000375 last_exc = saved_exc = None
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000376 saved_tb = None
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000377 for dir in PATH:
378 fullname = path.join(dir, file)
379 try:
Guido van Rossum68468eb2003-02-27 20:14:51 +0000380 func(fullname, *argrest)
Guido van Rossumb940e112007-01-10 16:19:56 +0000381 except error as e:
Guido van Rossume7ba4952007-06-06 23:52:48 +0000382 last_exc = e
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000383 tb = sys.exc_info()[2]
384 if (e.errno != ENOENT and e.errno != ENOTDIR
385 and saved_exc is None):
386 saved_exc = e
387 saved_tb = tb
388 if saved_exc:
389 raise error, saved_exc, saved_tb
Guido van Rossume7ba4952007-06-06 23:52:48 +0000390 raise error, last_exc, tb
Guido van Rossumd74fb6b2001-03-02 06:43:49 +0000391
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000392
Skip Montanaro289bc052007-08-17 02:30:27 +0000393# Change environ to automatically call putenv(), unsetenv if they exist.
394from _abcoll import MutableMapping # Can't use collections (bootstrap)
395
396class _Environ(MutableMapping):
397 def __init__(self, environ, keymap, putenv, unsetenv):
398 self.keymap = keymap
399 self.putenv = putenv
400 self.unsetenv = unsetenv
401 self.data = data = {}
402 for key, value in environ.items():
403 data[keymap(key)] = str(value)
404 def __getitem__(self, key):
405 return self.data[self.keymap(key)]
406 def __setitem__(self, key, value):
407 value = str(value)
408 self.putenv(key, value)
409 self.data[self.keymap(key)] = value
410 def __delitem__(self, key):
411 self.unsetenv(key)
412 del self.data[self.keymap(key)]
413 def __iter__(self):
414 for key in self.data:
415 yield key
416 def __len__(self):
417 return len(self.data)
418 def copy(self):
419 return dict(self)
420 def setdefault(self, key, value):
421 if key not in self:
422 self[key] = value
423 return self[key]
424
425try:
426 _putenv = putenv
427except NameError:
428 _putenv = lambda key, value: None
Martin v. Löwisa90f4382001-03-07 09:05:45 +0000429else:
Skip Montanaro289bc052007-08-17 02:30:27 +0000430 __all__.append("putenv")
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000431
Skip Montanaro289bc052007-08-17 02:30:27 +0000432try:
433 _unsetenv = unsetenv
434except NameError:
435 _unsetenv = lambda key: _putenv(key, "")
436else:
437 __all__.append("unsetenv")
Guido van Rossumc524d952001-10-19 01:31:59 +0000438
Skip Montanaro289bc052007-08-17 02:30:27 +0000439if name in ('os2', 'nt'): # Where Env Var Names Must Be UPPERCASE
440 _keymap = lambda key: str(key.upper())
441else: # Where Env Var Names Can Be Mixed Case
442 _keymap = lambda key: str(key)
Guido van Rossumc524d952001-10-19 01:31:59 +0000443
Skip Montanaro289bc052007-08-17 02:30:27 +0000444environ = _Environ(environ, _keymap, _putenv, _unsetenv)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000445
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000446
Jack Jansenb11ce9b2003-01-08 16:33:40 +0000447def getenv(key, default=None):
Tim Peters2c60f7a2003-01-29 03:49:43 +0000448 """Get an environment variable, return None if it doesn't exist.
449 The optional second argument can specify an alternate default."""
450 return environ.get(key, default)
Jack Jansenb11ce9b2003-01-08 16:33:40 +0000451__all__.append("getenv")
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000452
453def _exists(name):
454 try:
455 eval(name)
Tim Petersbc0e9102002-04-04 22:55:58 +0000456 return True
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000457 except NameError:
Tim Petersbc0e9102002-04-04 22:55:58 +0000458 return False
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000459
460# Supply spawn*() (probably only for Unix)
461if _exists("fork") and not _exists("spawnv") and _exists("execv"):
462
463 P_WAIT = 0
464 P_NOWAIT = P_NOWAITO = 1
465
466 # XXX Should we support P_DETACH? I suppose it could fork()**2
467 # and close the std I/O streams. Also, P_OVERLAY is the same
468 # as execv*()?
469
470 def _spawnvef(mode, file, args, env, func):
471 # Internal helper; func is the exec*() function to use
472 pid = fork()
473 if not pid:
474 # Child
475 try:
476 if env is None:
477 func(file, args)
478 else:
479 func(file, args, env)
480 except:
481 _exit(127)
482 else:
483 # Parent
484 if mode == P_NOWAIT:
485 return pid # Caller is responsible for waiting!
486 while 1:
487 wpid, sts = waitpid(pid, 0)
488 if WIFSTOPPED(sts):
489 continue
490 elif WIFSIGNALED(sts):
491 return -WTERMSIG(sts)
492 elif WIFEXITED(sts):
493 return WEXITSTATUS(sts)
494 else:
495 raise error, "Not stopped, signaled or exited???"
496
497 def spawnv(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000498 """spawnv(mode, file, args) -> integer
499
500Execute file with arguments from args in a subprocess.
501If mode == P_NOWAIT return the pid of the process.
502If mode == P_WAIT return the process's exit code if it exits normally;
Tim Peters2344fae2001-01-15 00:50:52 +0000503otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000504 return _spawnvef(mode, file, args, None, execv)
505
506 def spawnve(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000507 """spawnve(mode, file, args, env) -> integer
508
509Execute file with arguments from args in a subprocess with the
510specified environment.
511If mode == P_NOWAIT return the pid of the process.
512If mode == P_WAIT return the process's exit code if it exits normally;
513otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000514 return _spawnvef(mode, file, args, env, execve)
515
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000516 # Note: spawnvp[e] is't currently supported on Windows
517
518 def spawnvp(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000519 """spawnvp(mode, file, args) -> integer
520
521Execute file (which is looked for along $PATH) with arguments from
522args in a subprocess.
523If mode == P_NOWAIT return the pid of the process.
524If mode == P_WAIT return the process's exit code if it exits normally;
525otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000526 return _spawnvef(mode, file, args, None, execvp)
527
528 def spawnvpe(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000529 """spawnvpe(mode, file, args, env) -> integer
530
531Execute file (which is looked for along $PATH) with arguments from
532args in a subprocess with the supplied environment.
533If mode == P_NOWAIT return the pid of the process.
534If mode == P_WAIT return the process's exit code if it exits normally;
535otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000536 return _spawnvef(mode, file, args, env, execvpe)
537
538if _exists("spawnv"):
539 # These aren't supplied by the basic Windows code
540 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000541
542 def spawnl(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000543 """spawnl(mode, file, *args) -> integer
544
545Execute file with arguments from args in a subprocess.
546If mode == P_NOWAIT return the pid of the process.
547If mode == P_WAIT return the process's exit code if it exits normally;
548otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000549 return spawnv(mode, file, args)
550
551 def spawnle(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000552 """spawnle(mode, file, *args, env) -> integer
553
554Execute file with arguments from args in a subprocess with the
555supplied environment.
556If mode == P_NOWAIT return the pid of the process.
557If mode == P_WAIT return the process's exit code if it exits normally;
558otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000559 env = args[-1]
560 return spawnve(mode, file, args[:-1], env)
561
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000562
563 __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
564
565
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000566if _exists("spawnvp"):
567 # At the moment, Windows doesn't implement spawnvp[e],
568 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000569 def spawnlp(mode, file, *args):
Neal Norwitzb7f68102003-07-02 02:49:33 +0000570 """spawnlp(mode, file, *args) -> integer
Guido van Rossume0cd2912000-04-21 18:35:36 +0000571
572Execute file (which is looked for along $PATH) with arguments from
573args in a subprocess with the supplied environment.
574If mode == P_NOWAIT return the pid of the process.
575If mode == P_WAIT return the process's exit code if it exits normally;
576otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000577 return spawnvp(mode, file, args)
578
579 def spawnlpe(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000580 """spawnlpe(mode, file, *args, env) -> integer
581
582Execute file (which is looked for along $PATH) with arguments from
583args in a subprocess with the supplied environment.
584If mode == P_NOWAIT return the pid of the process.
585If mode == P_WAIT return the process's exit code if it exits normally;
586otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000587 env = args[-1]
588 return spawnvpe(mode, file, args[:-1], env)
Guido van Rossume0cd2912000-04-21 18:35:36 +0000589
590
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000591 __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
Skip Montanaro269b83b2001-02-06 01:07:02 +0000592
Michael W. Hudson0e025302002-03-06 17:11:18 +0000593import copy_reg as _copy_reg
594
595def _make_stat_result(tup, dict):
596 return stat_result(tup, dict)
597
598def _pickle_stat_result(sr):
599 (type, args) = sr.__reduce__()
600 return (_make_stat_result, args)
601
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000602try:
603 _copy_reg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
604except NameError: # stat_result may not exist
605 pass
Michael W. Hudson0e025302002-03-06 17:11:18 +0000606
607def _make_statvfs_result(tup, dict):
608 return statvfs_result(tup, dict)
609
610def _pickle_statvfs_result(sr):
611 (type, args) = sr.__reduce__()
612 return (_make_statvfs_result, args)
613
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000614try:
615 _copy_reg.pickle(statvfs_result, _pickle_statvfs_result,
616 _make_statvfs_result)
Michael W. Hudsone5363b72002-03-15 10:21:59 +0000617except NameError: # statvfs_result may not exist
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000618 pass
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000619
620if not _exists("urandom"):
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000621 def urandom(n):
622 """urandom(n) -> str
Tim Peters45e77c52004-08-29 18:47:31 +0000623
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000624 Return a string of n random bytes suitable for cryptographic use.
625
Tim Peters45e77c52004-08-29 18:47:31 +0000626 """
Georg Brandl9e43acf2005-07-04 17:16:07 +0000627 try:
628 _urandomfd = open("/dev/urandom", O_RDONLY)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000629 except (OSError, IOError):
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000630 raise NotImplementedError("/dev/urandom (or equivalent) not found")
Guido van Rossum572dbf82007-04-27 23:53:51 +0000631 bs = b""
632 while len(bs) < n:
633 bs += read(_urandomfd, n - len(bs))
Georg Brandl9e43acf2005-07-04 17:16:07 +0000634 close(_urandomfd)
Guido van Rossum572dbf82007-04-27 23:53:51 +0000635 return bs
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000636
637# Supply os.popen()
638def popen(cmd, mode="r", buffering=None):
639 if not isinstance(cmd, basestring):
640 raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
641 if mode not in ("r", "w"):
642 raise ValueError("invalid mode %r" % mode)
643 import subprocess, io
644 if mode == "r":
645 proc = subprocess.Popen(cmd,
646 shell=True,
647 stdout=subprocess.PIPE,
648 bufsize=buffering)
649 return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
650 else:
651 proc = subprocess.Popen(cmd,
652 shell=True,
653 stdin=subprocess.PIPE,
654 bufsize=buffering)
655 return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
656
657# Helper for popen() -- a proxy for a file whose close waits for the process
658class _wrap_close:
659 def __init__(self, stream, proc):
660 self._stream = stream
661 self._proc = proc
662 def close(self):
663 self._stream.close()
664 return self._proc.wait() << 8 # Shift left to match old behavior
665 def __getattr__(self, name):
666 return getattr(self._stream, name)
667
668# Supply os.fdopen() (used by subprocess!)
669def fdopen(fd, mode="r", buffering=-1):
670 if not isinstance(fd, int):
671 raise TypeError("invalid fd type (%s, expected integer)" % type(fd))
672 import io
673 return io.open(fd, mode, buffering)