blob: b5ade28876ca8777681576483d91064d44e66f5c [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
Christian Heimes45f9af32007-11-27 21:50:00 +000025import sys, errno
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:
Collin Winter828f04a2007-08-31 00:04:24 +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 """
143 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000144 if not tail:
145 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000146 if head and tail and not path.exists(head):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000147 try:
148 makedirs(head, mode)
Guido van Rossumb940e112007-01-10 16:19:56 +0000149 except OSError as e:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000150 # be happy if someone already created the path
Christian Heimes45f9af32007-11-27 21:50:00 +0000151 if e.errno != errno.EEXIST:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000152 raise
Andrew M. Kuchling6fccc8a2003-12-23 16:33:28 +0000153 if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists
154 return
Guido van Rossum4def7de1998-07-24 20:48:03 +0000155 mkdir(name, mode)
156
157def removedirs(name):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000158 """removedirs(path)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000159
Fredrik Lundh96c1c7a2005-11-12 15:55:04 +0000160 Super-rmdir; remove a leaf directory and all empty intermediate
Guido van Rossum4def7de1998-07-24 20:48:03 +0000161 ones. Works like rmdir except that, if the leaf directory is
162 successfully removed, directories corresponding to rightmost path
Tim Petersc4e09402003-04-25 07:11:48 +0000163 segments will be pruned away until either the whole path is
Guido van Rossum4def7de1998-07-24 20:48:03 +0000164 consumed or an error occurs. Errors during this latter phase are
165 ignored -- they generally mean that a directory was not empty.
166
167 """
168 rmdir(name)
169 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000170 if not tail:
171 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000172 while head and tail:
173 try:
174 rmdir(head)
175 except error:
176 break
177 head, tail = path.split(head)
178
179def renames(old, new):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000180 """renames(old, new)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000181
182 Super-rename; create directories as necessary and delete any left
183 empty. Works like rename, except creation of any intermediate
184 directories needed to make the new pathname good is attempted
185 first. After the rename, directories corresponding to rightmost
186 path segments of the old name will be pruned way until either the
187 whole path is consumed or a nonempty directory is found.
188
189 Note: this function can fail with the new directory structure made
190 if you lack permissions needed to unlink the leaf directory or
191 file.
192
193 """
194 head, tail = path.split(new)
195 if head and tail and not path.exists(head):
196 makedirs(head)
197 rename(old, new)
198 head, tail = path.split(old)
199 if head and tail:
200 try:
201 removedirs(head)
202 except error:
203 pass
204
Skip Montanaro269b83b2001-02-06 01:07:02 +0000205__all__.extend(["makedirs", "removedirs", "renames"])
206
Guido van Rossumd8faa362007-04-27 19:54:29 +0000207def walk(top, topdown=True, onerror=None, followlinks=False):
Tim Petersc4e09402003-04-25 07:11:48 +0000208 """Directory tree generator.
209
210 For each directory in the directory tree rooted at top (including top
211 itself, but excluding '.' and '..'), yields a 3-tuple
212
213 dirpath, dirnames, filenames
214
215 dirpath is a string, the path to the directory. dirnames is a list of
216 the names of the subdirectories in dirpath (excluding '.' and '..').
217 filenames is a list of the names of the non-directory files in dirpath.
218 Note that the names in the lists are just names, with no path components.
219 To get a full path (which begins with top) to a file or directory in
220 dirpath, do os.path.join(dirpath, name).
221
222 If optional arg 'topdown' is true or not specified, the triple for a
223 directory is generated before the triples for any of its subdirectories
224 (directories are generated top down). If topdown is false, the triple
225 for a directory is generated after the triples for all of its
226 subdirectories (directories are generated bottom up).
227
228 When topdown is true, the caller can modify the dirnames list in-place
229 (e.g., via del or slice assignment), and walk will only recurse into the
230 subdirectories whose names remain in dirnames; this can be used to prune
231 the search, or to impose a specific order of visiting. Modifying
232 dirnames when topdown is false is ineffective, since the directories in
233 dirnames have already been generated by the time dirnames itself is
234 generated.
235
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000236 By default errors from the os.listdir() call are ignored. If
237 optional arg 'onerror' is specified, it should be a function; it
238 will be called with one argument, an os.error instance. It can
239 report the error to continue with the walk, or raise the exception
240 to abort the walk. Note that the filename is available as the
241 filename attribute of the exception object.
242
Guido van Rossumd8faa362007-04-27 19:54:29 +0000243 By default, os.walk does not follow symbolic links to subdirectories on
244 systems that support them. In order to get this functionality, set the
245 optional argument 'followlinks' to true.
246
Tim Petersc4e09402003-04-25 07:11:48 +0000247 Caution: if you pass a relative pathname for top, don't change the
248 current working directory between resumptions of walk. walk never
249 changes the current directory, and assumes that the client doesn't
250 either.
251
252 Example:
253
Christian Heimes5d8da202008-05-06 13:58:24 +0000254 import os
Tim Petersc4e09402003-04-25 07:11:48 +0000255 from os.path import join, getsize
Christian Heimes5d8da202008-05-06 13:58:24 +0000256 for root, dirs, files in os.walk('python/Lib/email'):
Neal Norwitz752abd02008-05-13 04:55:24 +0000257 print(root, "consumes", end="")
258 print(sum([getsize(join(root, name)) for name in files]), end="")
259 print("bytes in", len(files), "non-directory files")
Tim Petersc4e09402003-04-25 07:11:48 +0000260 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
Alexandre Vassalotti4e6531e2008-05-09 20:00:17 +0000267 # get a list of the files the directory contains. os.walk
Tim Petersc4e09402003-04-25 07:11:48 +0000268 # 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):
356 if env is not None:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000357 func = execve
358 argrest = (args, env)
359 else:
360 func = execv
361 argrest = (args,)
362 env = environ
Guido van Rossumaed51d82002-08-05 16:13:24 +0000363
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000364 head, tail = path.split(file)
365 if head:
Guido van Rossum68468eb2003-02-27 20:14:51 +0000366 func(file, *argrest)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000367 return
Raymond Hettinger54f02222002-06-01 14:18:47 +0000368 if 'PATH' in env:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000369 envpath = env['PATH']
370 else:
371 envpath = defpath
Guido van Rossum965fdae2000-04-04 19:50:04 +0000372 PATH = envpath.split(pathsep)
Guido van Rossume7ba4952007-06-06 23:52:48 +0000373 last_exc = saved_exc = None
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000374 saved_tb = None
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000375 for dir in PATH:
376 fullname = path.join(dir, file)
377 try:
Guido van Rossum68468eb2003-02-27 20:14:51 +0000378 func(fullname, *argrest)
Guido van Rossumb940e112007-01-10 16:19:56 +0000379 except error as e:
Guido van Rossume7ba4952007-06-06 23:52:48 +0000380 last_exc = e
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000381 tb = sys.exc_info()[2]
Christian Heimes45f9af32007-11-27 21:50:00 +0000382 if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000383 and saved_exc is None):
384 saved_exc = e
385 saved_tb = tb
386 if saved_exc:
Collin Winter828f04a2007-08-31 00:04:24 +0000387 raise error(saved_exc).with_traceback(saved_tb)
388 raise error(last_exc).with_traceback(tb)
Guido van Rossumd74fb6b2001-03-02 06:43:49 +0000389
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000390
Skip Montanaro289bc052007-08-17 02:30:27 +0000391# Change environ to automatically call putenv(), unsetenv if they exist.
392from _abcoll import MutableMapping # Can't use collections (bootstrap)
393
394class _Environ(MutableMapping):
395 def __init__(self, environ, keymap, putenv, unsetenv):
396 self.keymap = keymap
397 self.putenv = putenv
398 self.unsetenv = unsetenv
399 self.data = data = {}
400 for key, value in environ.items():
401 data[keymap(key)] = str(value)
402 def __getitem__(self, key):
403 return self.data[self.keymap(key)]
404 def __setitem__(self, key, value):
405 value = str(value)
406 self.putenv(key, value)
407 self.data[self.keymap(key)] = value
408 def __delitem__(self, key):
409 self.unsetenv(key)
410 del self.data[self.keymap(key)]
411 def __iter__(self):
412 for key in self.data:
413 yield key
414 def __len__(self):
415 return len(self.data)
416 def copy(self):
417 return dict(self)
418 def setdefault(self, key, value):
419 if key not in self:
420 self[key] = value
421 return self[key]
422
423try:
424 _putenv = putenv
425except NameError:
426 _putenv = lambda key, value: None
Martin v. Löwisa90f4382001-03-07 09:05:45 +0000427else:
Skip Montanaro289bc052007-08-17 02:30:27 +0000428 __all__.append("putenv")
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000429
Skip Montanaro289bc052007-08-17 02:30:27 +0000430try:
431 _unsetenv = unsetenv
432except NameError:
433 _unsetenv = lambda key: _putenv(key, "")
434else:
435 __all__.append("unsetenv")
Guido van Rossumc524d952001-10-19 01:31:59 +0000436
Skip Montanaro289bc052007-08-17 02:30:27 +0000437if name in ('os2', 'nt'): # Where Env Var Names Must Be UPPERCASE
438 _keymap = lambda key: str(key.upper())
439else: # Where Env Var Names Can Be Mixed Case
440 _keymap = lambda key: str(key)
Guido van Rossumc524d952001-10-19 01:31:59 +0000441
Skip Montanaro289bc052007-08-17 02:30:27 +0000442environ = _Environ(environ, _keymap, _putenv, _unsetenv)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000443
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000444
Jack Jansenb11ce9b2003-01-08 16:33:40 +0000445def getenv(key, default=None):
Tim Peters2c60f7a2003-01-29 03:49:43 +0000446 """Get an environment variable, return None if it doesn't exist.
447 The optional second argument can specify an alternate default."""
448 return environ.get(key, default)
Jack Jansenb11ce9b2003-01-08 16:33:40 +0000449__all__.append("getenv")
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000450
451def _exists(name):
452 try:
453 eval(name)
Tim Petersbc0e9102002-04-04 22:55:58 +0000454 return True
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000455 except NameError:
Tim Petersbc0e9102002-04-04 22:55:58 +0000456 return False
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000457
458# Supply spawn*() (probably only for Unix)
459if _exists("fork") and not _exists("spawnv") and _exists("execv"):
460
461 P_WAIT = 0
462 P_NOWAIT = P_NOWAITO = 1
463
464 # XXX Should we support P_DETACH? I suppose it could fork()**2
465 # and close the std I/O streams. Also, P_OVERLAY is the same
466 # as execv*()?
467
468 def _spawnvef(mode, file, args, env, func):
469 # Internal helper; func is the exec*() function to use
470 pid = fork()
471 if not pid:
472 # Child
473 try:
474 if env is None:
475 func(file, args)
476 else:
477 func(file, args, env)
478 except:
479 _exit(127)
480 else:
481 # Parent
482 if mode == P_NOWAIT:
483 return pid # Caller is responsible for waiting!
484 while 1:
485 wpid, sts = waitpid(pid, 0)
486 if WIFSTOPPED(sts):
487 continue
488 elif WIFSIGNALED(sts):
489 return -WTERMSIG(sts)
490 elif WIFEXITED(sts):
491 return WEXITSTATUS(sts)
492 else:
Collin Winter828f04a2007-08-31 00:04:24 +0000493 raise error("Not stopped, signaled or exited???")
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000494
495 def spawnv(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000496 """spawnv(mode, file, args) -> integer
497
498Execute file with arguments from args in a subprocess.
499If mode == P_NOWAIT return the pid of the process.
500If mode == P_WAIT return the process's exit code if it exits normally;
Tim Peters2344fae2001-01-15 00:50:52 +0000501otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000502 return _spawnvef(mode, file, args, None, execv)
503
504 def spawnve(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000505 """spawnve(mode, file, args, env) -> integer
506
507Execute file with arguments from args in a subprocess with the
508specified environment.
509If mode == P_NOWAIT return the pid of the process.
510If mode == P_WAIT return the process's exit code if it exits normally;
511otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000512 return _spawnvef(mode, file, args, env, execve)
513
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000514 # Note: spawnvp[e] is't currently supported on Windows
515
516 def spawnvp(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000517 """spawnvp(mode, file, args) -> integer
518
519Execute file (which is looked for along $PATH) with arguments from
520args in a subprocess.
521If mode == P_NOWAIT return the pid of the process.
522If mode == P_WAIT return the process's exit code if it exits normally;
523otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000524 return _spawnvef(mode, file, args, None, execvp)
525
526 def spawnvpe(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000527 """spawnvpe(mode, file, args, env) -> integer
528
529Execute file (which is looked for along $PATH) with arguments from
530args in a subprocess with the supplied environment.
531If mode == P_NOWAIT return the pid of the process.
532If mode == P_WAIT return the process's exit code if it exits normally;
533otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000534 return _spawnvef(mode, file, args, env, execvpe)
535
536if _exists("spawnv"):
537 # These aren't supplied by the basic Windows code
538 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000539
540 def spawnl(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000541 """spawnl(mode, file, *args) -> integer
542
543Execute file with arguments from args in a subprocess.
544If mode == P_NOWAIT return the pid of the process.
545If mode == P_WAIT return the process's exit code if it exits normally;
546otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000547 return spawnv(mode, file, args)
548
549 def spawnle(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000550 """spawnle(mode, file, *args, env) -> integer
551
552Execute file with arguments from args in a subprocess with the
553supplied environment.
554If mode == P_NOWAIT return the pid of the process.
555If mode == P_WAIT return the process's exit code if it exits normally;
556otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000557 env = args[-1]
558 return spawnve(mode, file, args[:-1], env)
559
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000560
561 __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
562
563
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000564if _exists("spawnvp"):
565 # At the moment, Windows doesn't implement spawnvp[e],
566 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000567 def spawnlp(mode, file, *args):
Neal Norwitzb7f68102003-07-02 02:49:33 +0000568 """spawnlp(mode, file, *args) -> integer
Guido van Rossume0cd2912000-04-21 18:35:36 +0000569
570Execute file (which is looked for along $PATH) with arguments from
571args in a subprocess with the supplied environment.
572If mode == P_NOWAIT return the pid of the process.
573If mode == P_WAIT return the process's exit code if it exits normally;
574otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000575 return spawnvp(mode, file, args)
576
577 def spawnlpe(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000578 """spawnlpe(mode, file, *args, env) -> integer
579
580Execute file (which is looked for along $PATH) with arguments from
581args in a subprocess with the supplied environment.
582If mode == P_NOWAIT return the pid of the process.
583If mode == P_WAIT return the process's exit code if it exits normally;
584otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000585 env = args[-1]
586 return spawnvpe(mode, file, args[:-1], env)
Guido van Rossume0cd2912000-04-21 18:35:36 +0000587
588
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000589 __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
Skip Montanaro269b83b2001-02-06 01:07:02 +0000590
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000591import copyreg as _copyreg
Michael W. Hudson0e025302002-03-06 17:11:18 +0000592
593def _make_stat_result(tup, dict):
594 return stat_result(tup, dict)
595
596def _pickle_stat_result(sr):
597 (type, args) = sr.__reduce__()
598 return (_make_stat_result, args)
599
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000600try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000601 _copyreg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000602except NameError: # stat_result may not exist
603 pass
Michael W. Hudson0e025302002-03-06 17:11:18 +0000604
605def _make_statvfs_result(tup, dict):
606 return statvfs_result(tup, dict)
607
608def _pickle_statvfs_result(sr):
609 (type, args) = sr.__reduce__()
610 return (_make_statvfs_result, args)
611
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000612try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000613 _copyreg.pickle(statvfs_result, _pickle_statvfs_result,
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000614 _make_statvfs_result)
Michael W. Hudsone5363b72002-03-15 10:21:59 +0000615except NameError: # statvfs_result may not exist
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000616 pass
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000617
618if not _exists("urandom"):
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000619 def urandom(n):
620 """urandom(n) -> str
Tim Peters45e77c52004-08-29 18:47:31 +0000621
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000622 Return a string of n random bytes suitable for cryptographic use.
623
Tim Peters45e77c52004-08-29 18:47:31 +0000624 """
Georg Brandl9e43acf2005-07-04 17:16:07 +0000625 try:
626 _urandomfd = open("/dev/urandom", O_RDONLY)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000627 except (OSError, IOError):
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000628 raise NotImplementedError("/dev/urandom (or equivalent) not found")
Guido van Rossum572dbf82007-04-27 23:53:51 +0000629 bs = b""
630 while len(bs) < n:
631 bs += read(_urandomfd, n - len(bs))
Georg Brandl9e43acf2005-07-04 17:16:07 +0000632 close(_urandomfd)
Guido van Rossum572dbf82007-04-27 23:53:51 +0000633 return bs
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000634
635# Supply os.popen()
636def popen(cmd, mode="r", buffering=None):
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000637 if not isinstance(cmd, str):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000638 raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
639 if mode not in ("r", "w"):
640 raise ValueError("invalid mode %r" % mode)
641 import subprocess, io
642 if mode == "r":
643 proc = subprocess.Popen(cmd,
644 shell=True,
645 stdout=subprocess.PIPE,
646 bufsize=buffering)
647 return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
648 else:
649 proc = subprocess.Popen(cmd,
650 shell=True,
651 stdin=subprocess.PIPE,
652 bufsize=buffering)
653 return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
654
655# Helper for popen() -- a proxy for a file whose close waits for the process
656class _wrap_close:
657 def __init__(self, stream, proc):
658 self._stream = stream
659 self._proc = proc
660 def close(self):
661 self._stream.close()
662 return self._proc.wait() << 8 # Shift left to match old behavior
663 def __getattr__(self, name):
664 return getattr(self._stream, name)
Thomas Heller476157b2007-09-04 11:27:47 +0000665 def __iter__(self):
666 return iter(self._stream)
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000667
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)