blob: 261a39e64b32be60a2a647148821e917ea8d08a1 [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:
Alexandre Vassalottieca20b62008-05-16 02:54:33 +00004 - all functions from posix, nt, os2, or ce, e.g. unlink, stat, etc.
5 - os.path is either posixpath or ntpath
6 - os.name is either 'posix', 'nt', 'os2' 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 '\\')
Georg Brandled5b9b32008-12-05 07:45:54 +000010 - os.extsep is the extension separator (always '.')
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
Martin v. Löwisbdec50f2004-06-08 08:29:33 +000015 - os.devnull is the file path of the null device ('/dev/null', etc.)
Guido van Rossum31104f41992-01-14 18:28:36 +000016
Guido van Rossum54f22ed2000-02-04 15:10:34 +000017Programs that import and use 'os' stand a better chance of being
18portable between different platforms. Of course, they must then
19only use functions that are defined by all platforms (e.g., unlink
20and opendir), and leave all pathname manipulation to os.path
21(e.g., split and join).
22"""
Guido van Rossum31104f41992-01-14 18:28:36 +000023
Skip Montanaro269b83b2001-02-06 01:07:02 +000024#'
25
Christian Heimes45f9af32007-11-27 21:50:00 +000026import sys, errno
Charles-François Natali7372b062012-02-05 15:15:38 +010027import stat as st
Guido van Rossuma28dab51997-08-29 22:36:47 +000028
29_names = sys.builtin_module_names
30
Tim Petersc4e09402003-04-25 07:11:48 +000031# Note: more names are added to __all__ later.
Brett Cannon13962fc2008-08-18 01:45:29 +000032__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
Petri Lehtinen3bc37f22012-05-23 21:36:16 +030033 "defpath", "name", "path", "devnull", "SEEK_SET", "SEEK_CUR",
34 "SEEK_END", "fsencode", "fsdecode", "get_exec_path", "fdopen",
35 "popen", "extsep"]
Skip Montanaro269b83b2001-02-06 01:07:02 +000036
Charles-François Natali7372b062012-02-05 15:15:38 +010037def _exists(name):
38 return name in globals()
39
Skip Montanaro269b83b2001-02-06 01:07:02 +000040def _get_exports_list(module):
41 try:
42 return list(module.__all__)
43 except AttributeError:
44 return [n for n in dir(module) if n[0] != '_']
45
Brett Cannonfd074152012-04-14 14:10:13 -040046# Any new dependencies of the os module and/or changes in path separator
47# requires updating importlib as well.
Guido van Rossuma28dab51997-08-29 22:36:47 +000048if 'posix' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000049 name = 'posix'
Guido van Rossume9387ea1998-05-22 15:26:04 +000050 linesep = '\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000051 from posix import *
52 try:
53 from posix import _exit
Petri Lehtinen3bc37f22012-05-23 21:36:16 +030054 __all__.append('_exit')
Guido van Rossum61de0ac1997-12-05 21:24:30 +000055 except ImportError:
56 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000057 import posixpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000058
Skip Montanaro269b83b2001-02-06 01:07:02 +000059 import posix
60 __all__.extend(_get_exports_list(posix))
61 del posix
62
Guido van Rossuma28dab51997-08-29 22:36:47 +000063elif 'nt' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000064 name = 'nt'
Guido van Rossume9387ea1998-05-22 15:26:04 +000065 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000066 from nt import *
Tim Peters6757c1e2003-01-08 21:20:57 +000067 try:
68 from nt import _exit
Petri Lehtinen3bc37f22012-05-23 21:36:16 +030069 __all__.append('_exit')
Tim Peters6757c1e2003-01-08 21:20:57 +000070 except ImportError:
71 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000072 import ntpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000073
Skip Montanaro269b83b2001-02-06 01:07:02 +000074 import nt
75 __all__.extend(_get_exports_list(nt))
76 del nt
77
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000078elif 'os2' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000079 name = 'os2'
Guido van Rossume9387ea1998-05-22 15:26:04 +000080 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000081 from os2 import *
82 try:
83 from os2 import _exit
Petri Lehtinen3bc37f22012-05-23 21:36:16 +030084 __all__.append('_exit')
Guido van Rossum61de0ac1997-12-05 21:24:30 +000085 except ImportError:
86 pass
Andrew MacIntyre5cef5712002-02-24 05:32:32 +000087 if sys.version.find('EMX GCC') == -1:
Skip Montanaro117910d2003-02-14 19:35:31 +000088 import ntpath as path
Andrew MacIntyre5cef5712002-02-24 05:32:32 +000089 else:
Skip Montanaro117910d2003-02-14 19:35:31 +000090 import os2emxpath as path
Andrew MacIntyre89f98652003-12-02 12:33:01 +000091 from _emx_link import link
Tim Petersf2715e02003-02-19 02:35:07 +000092
Skip Montanaro269b83b2001-02-06 01:07:02 +000093 import os2
94 __all__.extend(_get_exports_list(os2))
95 del os2
96
Guido van Rossum18df5d41999-06-11 01:37:27 +000097elif 'ce' in _names:
98 name = 'ce'
99 linesep = '\r\n'
Guido van Rossum18df5d41999-06-11 01:37:27 +0000100 from ce import *
Tim Peters6757c1e2003-01-08 21:20:57 +0000101 try:
102 from ce import _exit
Petri Lehtinen3bc37f22012-05-23 21:36:16 +0300103 __all__.append('_exit')
Tim Peters6757c1e2003-01-08 21:20:57 +0000104 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 Rossum2979b011994-08-01 11:18:30 +0000113else:
Collin Winter828f04a2007-08-31 00:04:24 +0000114 raise ImportError('no os specific module found')
Guido van Rossume65cce51993-11-08 15:05:21 +0000115
Skip Montanaro117910d2003-02-14 19:35:31 +0000116sys.modules['os.path'] = path
Georg Brandled5b9b32008-12-05 07:45:54 +0000117from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
118 devnull)
Skip Montanaro269b83b2001-02-06 01:07:02 +0000119
Guido van Rossuma28dab51997-08-29 22:36:47 +0000120del _names
121
Martin v. Löwis22b457e2005-01-16 08:40:58 +0000122# Python uses fixed values for the SEEK_ constants; they are mapped
123# to native constants if necessary in posixmodule.c
Jesus Cea94363612012-06-22 18:32:07 +0200124# Other possible SEEK values are directly imported from posixmodule.c
Martin v. Löwis22b457e2005-01-16 08:40:58 +0000125SEEK_SET = 0
126SEEK_CUR = 1
127SEEK_END = 2
128
Terry Reedy5a22b652010-12-02 07:05:56 +0000129
130def _get_masked_mode(mode):
131 mask = umask(0)
132 umask(mask)
133 return mode & ~mask
134
Guido van Rossum4def7de1998-07-24 20:48:03 +0000135# Super directory utilities.
136# (Inspired by Eric Raymond; the doc strings are mostly his)
137
Terry Reedy5a22b652010-12-02 07:05:56 +0000138def makedirs(name, mode=0o777, exist_ok=False):
139 """makedirs(path [, mode=0o777][, exist_ok=False])
Guido van Rossum4def7de1998-07-24 20:48:03 +0000140
141 Super-mkdir; create a leaf directory and all intermediate ones.
142 Works like mkdir, except that any intermediate path segment (not
Terry Reedy5a22b652010-12-02 07:05:56 +0000143 just the rightmost) will be created if it does not exist. If the
144 target directory with the same mode as we specified already exists,
145 raises an OSError if exist_ok is False, otherwise no exception is
146 raised. This is recursive.
Guido van Rossum4def7de1998-07-24 20:48:03 +0000147
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):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000153 try:
Terry Reedy5a22b652010-12-02 07:05:56 +0000154 makedirs(head, mode, exist_ok)
Guido van Rossumb940e112007-01-10 16:19:56 +0000155 except OSError as e:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000156 # be happy if someone already created the path
Christian Heimes45f9af32007-11-27 21:50:00 +0000157 if e.errno != errno.EEXIST:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000158 raise
Andrew M. Kuchling6fccc8a2003-12-23 16:33:28 +0000159 if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists
160 return
Terry Reedy5a22b652010-12-02 07:05:56 +0000161 try:
162 mkdir(name, mode)
163 except OSError as e:
Gregory P. Smitha81c8562012-06-03 14:30:44 -0700164 dir_exists = path.isdir(name)
165 expected_mode = _get_masked_mode(mode)
166 if dir_exists:
167 # S_ISGID is automatically copied by the OS from parent to child
168 # directories on mkdir. Don't consider it being set to be a mode
169 # mismatch as mkdir does not unset it when not specified in mode.
170 actual_mode = st.S_IMODE(lstat(name).st_mode) & ~st.S_ISGID
171 else:
172 actual_mode = -1
173 if not (e.errno == errno.EEXIST and exist_ok and dir_exists and
174 actual_mode == expected_mode):
175 if dir_exists and actual_mode != expected_mode:
176 e.strerror += ' (mode %o != expected mode %o)' % (
177 actual_mode, expected_mode)
Terry Reedy5a22b652010-12-02 07:05:56 +0000178 raise
Guido van Rossum4def7de1998-07-24 20:48:03 +0000179
180def removedirs(name):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000181 """removedirs(path)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000182
Fredrik Lundh96c1c7a2005-11-12 15:55:04 +0000183 Super-rmdir; remove a leaf directory and all empty intermediate
Guido van Rossum4def7de1998-07-24 20:48:03 +0000184 ones. Works like rmdir except that, if the leaf directory is
185 successfully removed, directories corresponding to rightmost path
Tim Petersc4e09402003-04-25 07:11:48 +0000186 segments will be pruned away until either the whole path is
Guido van Rossum4def7de1998-07-24 20:48:03 +0000187 consumed or an error occurs. Errors during this latter phase are
188 ignored -- they generally mean that a directory was not empty.
189
190 """
191 rmdir(name)
192 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000193 if not tail:
194 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000195 while head and tail:
196 try:
197 rmdir(head)
198 except error:
199 break
200 head, tail = path.split(head)
201
202def renames(old, new):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000203 """renames(old, new)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000204
205 Super-rename; create directories as necessary and delete any left
206 empty. Works like rename, except creation of any intermediate
207 directories needed to make the new pathname good is attempted
208 first. After the rename, directories corresponding to rightmost
209 path segments of the old name will be pruned way until either the
210 whole path is consumed or a nonempty directory is found.
211
212 Note: this function can fail with the new directory structure made
213 if you lack permissions needed to unlink the leaf directory or
214 file.
215
216 """
217 head, tail = path.split(new)
218 if head and tail and not path.exists(head):
219 makedirs(head)
220 rename(old, new)
221 head, tail = path.split(old)
222 if head and tail:
223 try:
224 removedirs(head)
225 except error:
226 pass
227
Skip Montanaro269b83b2001-02-06 01:07:02 +0000228__all__.extend(["makedirs", "removedirs", "renames"])
229
Guido van Rossumd8faa362007-04-27 19:54:29 +0000230def walk(top, topdown=True, onerror=None, followlinks=False):
Tim Petersc4e09402003-04-25 07:11:48 +0000231 """Directory tree generator.
232
233 For each directory in the directory tree rooted at top (including top
234 itself, but excluding '.' and '..'), yields a 3-tuple
235
236 dirpath, dirnames, filenames
237
238 dirpath is a string, the path to the directory. dirnames is a list of
239 the names of the subdirectories in dirpath (excluding '.' and '..').
240 filenames is a list of the names of the non-directory files in dirpath.
241 Note that the names in the lists are just names, with no path components.
242 To get a full path (which begins with top) to a file or directory in
243 dirpath, do os.path.join(dirpath, name).
244
245 If optional arg 'topdown' is true or not specified, the triple for a
246 directory is generated before the triples for any of its subdirectories
247 (directories are generated top down). If topdown is false, the triple
248 for a directory is generated after the triples for all of its
249 subdirectories (directories are generated bottom up).
250
251 When topdown is true, the caller can modify the dirnames list in-place
252 (e.g., via del or slice assignment), and walk will only recurse into the
253 subdirectories whose names remain in dirnames; this can be used to prune
254 the search, or to impose a specific order of visiting. Modifying
255 dirnames when topdown is false is ineffective, since the directories in
256 dirnames have already been generated by the time dirnames itself is
257 generated.
258
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000259 By default errors from the os.listdir() call are ignored. If
260 optional arg 'onerror' is specified, it should be a function; it
261 will be called with one argument, an os.error instance. It can
262 report the error to continue with the walk, or raise the exception
263 to abort the walk. Note that the filename is available as the
264 filename attribute of the exception object.
265
Guido van Rossumd8faa362007-04-27 19:54:29 +0000266 By default, os.walk does not follow symbolic links to subdirectories on
267 systems that support them. In order to get this functionality, set the
268 optional argument 'followlinks' to true.
269
Tim Petersc4e09402003-04-25 07:11:48 +0000270 Caution: if you pass a relative pathname for top, don't change the
271 current working directory between resumptions of walk. walk never
272 changes the current directory, and assumes that the client doesn't
273 either.
274
275 Example:
276
Christian Heimes5d8da202008-05-06 13:58:24 +0000277 import os
Tim Petersc4e09402003-04-25 07:11:48 +0000278 from os.path import join, getsize
Christian Heimes5d8da202008-05-06 13:58:24 +0000279 for root, dirs, files in os.walk('python/Lib/email'):
Neal Norwitz752abd02008-05-13 04:55:24 +0000280 print(root, "consumes", end="")
281 print(sum([getsize(join(root, name)) for name in files]), end="")
282 print("bytes in", len(files), "non-directory files")
Tim Petersc4e09402003-04-25 07:11:48 +0000283 if 'CVS' in dirs:
284 dirs.remove('CVS') # don't visit CVS directories
285 """
286
Benjamin Petersonf6489f92009-11-25 17:46:26 +0000287 islink, join, isdir = path.islink, path.join, path.isdir
Tim Petersc4e09402003-04-25 07:11:48 +0000288
289 # We may not have read permission for top, in which case we can't
Alexandre Vassalotti4e6531e2008-05-09 20:00:17 +0000290 # get a list of the files the directory contains. os.walk
Tim Petersc4e09402003-04-25 07:11:48 +0000291 # always suppressed the exception then, rather than blow up for a
292 # minor reason when (say) a thousand readable directories are still
293 # left to visit. That logic is copied here.
294 try:
295 # Note that listdir and error are globals in this module due
296 # to earlier import-*.
297 names = listdir(top)
Guido van Rossumb940e112007-01-10 16:19:56 +0000298 except error as err:
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000299 if onerror is not None:
300 onerror(err)
Tim Petersc4e09402003-04-25 07:11:48 +0000301 return
302
303 dirs, nondirs = [], []
304 for name in names:
305 if isdir(join(top, name)):
306 dirs.append(name)
307 else:
308 nondirs.append(name)
309
310 if topdown:
311 yield top, dirs, nondirs
312 for name in dirs:
Benjamin Petersonf6489f92009-11-25 17:46:26 +0000313 new_path = join(top, name)
314 if followlinks or not islink(new_path):
Benjamin Peterson569d0872012-05-10 16:17:35 -0500315 yield from walk(new_path, topdown, onerror, followlinks)
Tim Petersc4e09402003-04-25 07:11:48 +0000316 if not topdown:
317 yield top, dirs, nondirs
318
319__all__.append("walk")
320
Charles-François Natali7372b062012-02-05 15:15:38 +0100321if _exists("openat"):
322
323 def fwalk(top, topdown=True, onerror=None, followlinks=False):
324 """Directory tree generator.
325
326 This behaves exactly like walk(), except that it yields a 4-tuple
327
328 dirpath, dirnames, filenames, dirfd
329
330 `dirpath`, `dirnames` and `filenames` are identical to walk() output,
331 and `dirfd` is a file descriptor referring to the directory `dirpath`.
332
333 The advantage of walkfd() over walk() is that it's safe against symlink
334 races (when followlinks is False).
335
336 Caution:
337 Since fwalk() yields file descriptors, those are only valid until the
338 next iteration step, so you should dup() them if you want to keep them
339 for a longer period.
340
341 Example:
342
343 import os
344 for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
345 print(root, "consumes", end="")
346 print(sum([os.fstatat(rootfd, name).st_size for name in files]),
347 end="")
348 print("bytes in", len(files), "non-directory files")
349 if 'CVS' in dirs:
350 dirs.remove('CVS') # don't visit CVS directories
351 """
352 # Note: To guard against symlink races, we use the standard
353 # lstat()/open()/fstat() trick.
354 orig_st = lstat(top)
355 topfd = open(top, O_RDONLY)
356 try:
357 if (followlinks or (st.S_ISDIR(orig_st.st_mode) and
Charles-François Natali84c0ca02012-04-22 15:55:43 +0200358 path.samestat(orig_st, fstat(topfd)))):
Benjamin Peterson569d0872012-05-10 16:17:35 -0500359 yield from _fwalk(topfd, top, topdown, onerror, followlinks)
Charles-François Natali7372b062012-02-05 15:15:38 +0100360 finally:
361 close(topfd)
362
363 def _fwalk(topfd, toppath, topdown, onerror, followlinks):
364 # Note: This uses O(depth of the directory tree) file descriptors: if
365 # necessary, it can be adapted to only require O(1) FDs, see issue
366 # #13734.
367
368 # whether to follow symlinks
369 flag = 0 if followlinks else AT_SYMLINK_NOFOLLOW
370
Charles-François Natali77940902012-02-06 19:54:48 +0100371 names = flistdir(topfd)
Charles-François Natali7372b062012-02-05 15:15:38 +0100372 dirs, nondirs = [], []
373 for name in names:
Hynek Schlawack66bfcc12012-05-15 16:32:21 +0200374 try:
375 # Here, we don't use AT_SYMLINK_NOFOLLOW to be consistent with
376 # walk() which reports symlinks to directories as directories.
377 # We do however check for symlinks before recursing into
378 # a subdirectory.
379 if st.S_ISDIR(fstatat(topfd, name).st_mode):
380 dirs.append(name)
381 else:
382 nondirs.append(name)
383 except FileNotFoundError:
384 try:
385 # Add dangling symlinks, ignore disappeared files
386 if st.S_ISLNK(fstatat(topfd, name, AT_SYMLINK_NOFOLLOW)
387 .st_mode):
388 nondirs.append(name)
389 except FileNotFoundError:
390 continue
Charles-François Natali7372b062012-02-05 15:15:38 +0100391
392 if topdown:
393 yield toppath, dirs, nondirs, topfd
394
395 for name in dirs:
396 try:
397 orig_st = fstatat(topfd, name, flag)
398 dirfd = openat(topfd, name, O_RDONLY)
399 except error as err:
400 if onerror is not None:
401 onerror(err)
402 return
403 try:
Charles-François Natali84c0ca02012-04-22 15:55:43 +0200404 if followlinks or path.samestat(orig_st, fstat(dirfd)):
Charles-François Natali7372b062012-02-05 15:15:38 +0100405 dirpath = path.join(toppath, name)
Benjamin Peterson569d0872012-05-10 16:17:35 -0500406 yield from _fwalk(dirfd, dirpath, topdown, onerror, followlinks)
Charles-François Natali7372b062012-02-05 15:15:38 +0100407 finally:
408 close(dirfd)
409
410 if not topdown:
411 yield toppath, dirs, nondirs, topfd
412
413 __all__.append("fwalk")
414
Guido van Rossuma28dab51997-08-29 22:36:47 +0000415# Make sure os.environ exists, at least
416try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000417 environ
Guido van Rossuma28dab51997-08-29 22:36:47 +0000418except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000419 environ = {}
Guido van Rossuma28dab51997-08-29 22:36:47 +0000420
Guido van Rossume65cce51993-11-08 15:05:21 +0000421def execl(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000422 """execl(file, *args)
423
424 Execute the executable file with argument list args, replacing the
425 current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000426 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000427
428def execle(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000429 """execle(file, *args, env)
430
431 Execute the executable file with argument list args and
432 environment env, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000433 env = args[-1]
434 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000435
436def execlp(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000437 """execlp(file, *args)
438
439 Execute the executable file (which is searched for along $PATH)
440 with argument list args, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000441 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000442
Guido van Rossum030afb11995-03-14 17:27:18 +0000443def execlpe(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000444 """execlpe(file, *args, env)
445
446 Execute the executable file (which is searched for along $PATH)
447 with argument list args and environment env, replacing the current
Tim Peters2344fae2001-01-15 00:50:52 +0000448 process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000449 env = args[-1]
450 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000451
Guido van Rossume65cce51993-11-08 15:05:21 +0000452def execvp(file, args):
Matthias Klosea09c54f2010-01-31 16:48:44 +0000453 """execvp(file, args)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000454
455 Execute the executable file (which is searched for along $PATH)
456 with argument list args, replacing the current process.
Thomas Wouters7e474022000-07-16 12:04:32 +0000457 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000458 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000459
460def execvpe(file, args, env):
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000461 """execvpe(file, args, env)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000462
463 Execute the executable file (which is searched for along $PATH)
464 with argument list args and environment env , replacing the
465 current process.
Tim Peters2344fae2001-01-15 00:50:52 +0000466 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000467 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000468
Skip Montanaro269b83b2001-02-06 01:07:02 +0000469__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
470
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000471def _execvpe(file, args, env=None):
472 if env is not None:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000473 exec_func = execve
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000474 argrest = (args, env)
475 else:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000476 exec_func = execv
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000477 argrest = (args,)
478 env = environ
Guido van Rossumaed51d82002-08-05 16:13:24 +0000479
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000480 head, tail = path.split(file)
481 if head:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000482 exec_func(file, *argrest)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000483 return
Guido van Rossume7ba4952007-06-06 23:52:48 +0000484 last_exc = saved_exc = None
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000485 saved_tb = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000486 path_list = get_exec_path(env)
487 if name != 'nt':
488 file = fsencode(file)
489 path_list = map(fsencode, path_list)
490 for dir in path_list:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000491 fullname = path.join(dir, file)
492 try:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000493 exec_func(fullname, *argrest)
Guido van Rossumb940e112007-01-10 16:19:56 +0000494 except error as e:
Guido van Rossume7ba4952007-06-06 23:52:48 +0000495 last_exc = e
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000496 tb = sys.exc_info()[2]
Christian Heimes45f9af32007-11-27 21:50:00 +0000497 if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000498 and saved_exc is None):
499 saved_exc = e
500 saved_tb = tb
501 if saved_exc:
Benjamin Peterson4b068192009-02-20 03:19:25 +0000502 raise saved_exc.with_traceback(saved_tb)
503 raise last_exc.with_traceback(tb)
Guido van Rossumd74fb6b2001-03-02 06:43:49 +0000504
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000505
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000506def get_exec_path(env=None):
507 """Returns the sequence of directories that will be searched for the
508 named executable (similar to a shell) when launching a process.
509
510 *env* must be an environment variable dict or None. If *env* is None,
511 os.environ will be used.
512 """
Victor Stinner273b7662010-11-06 12:59:33 +0000513 # Use a local import instead of a global import to limit the number of
514 # modules loaded at startup: the os module is always loaded at startup by
515 # Python. It may also avoid a bootstrap issue.
Victor Stinner6f35eda2010-10-29 00:38:58 +0000516 import warnings
517
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000518 if env is None:
519 env = environ
Victor Stinnerb745a742010-05-18 17:17:23 +0000520
Victor Stinnerbb4f2182010-11-07 15:43:39 +0000521 # {b'PATH': ...}.get('PATH') and {'PATH': ...}.get(b'PATH') emit a
522 # BytesWarning when using python -b or python -bb: ignore the warning
Victor Stinner273b7662010-11-06 12:59:33 +0000523 with warnings.catch_warnings():
524 warnings.simplefilter("ignore", BytesWarning)
Victor Stinnerb745a742010-05-18 17:17:23 +0000525
Victor Stinnerb745a742010-05-18 17:17:23 +0000526 try:
Victor Stinner273b7662010-11-06 12:59:33 +0000527 path_list = env.get('PATH')
528 except TypeError:
529 path_list = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000530
Victor Stinner273b7662010-11-06 12:59:33 +0000531 if supports_bytes_environ:
532 try:
533 path_listb = env[b'PATH']
534 except (KeyError, TypeError):
535 pass
536 else:
537 if path_list is not None:
538 raise ValueError(
539 "env cannot contain 'PATH' and b'PATH' keys")
540 path_list = path_listb
541
542 if path_list is not None and isinstance(path_list, bytes):
543 path_list = fsdecode(path_list)
Victor Stinnerb745a742010-05-18 17:17:23 +0000544
545 if path_list is None:
546 path_list = defpath
547 return path_list.split(pathsep)
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000548
549
Skip Montanaro289bc052007-08-17 02:30:27 +0000550# Change environ to automatically call putenv(), unsetenv if they exist.
Raymond Hettinger158c9c22011-02-22 00:41:50 +0000551from collections.abc import MutableMapping
Skip Montanaro289bc052007-08-17 02:30:27 +0000552
553class _Environ(MutableMapping):
Victor Stinner84ae1182010-05-06 22:05:07 +0000554 def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue, putenv, unsetenv):
555 self.encodekey = encodekey
556 self.decodekey = decodekey
557 self.encodevalue = encodevalue
558 self.decodevalue = decodevalue
Skip Montanaro289bc052007-08-17 02:30:27 +0000559 self.putenv = putenv
560 self.unsetenv = unsetenv
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000561 self._data = data
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000562
Skip Montanaro289bc052007-08-17 02:30:27 +0000563 def __getitem__(self, key):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000564 value = self._data[self.encodekey(key)]
Victor Stinner84ae1182010-05-06 22:05:07 +0000565 return self.decodevalue(value)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000566
Skip Montanaro289bc052007-08-17 02:30:27 +0000567 def __setitem__(self, key, value):
Victor Stinner84ae1182010-05-06 22:05:07 +0000568 key = self.encodekey(key)
569 value = self.encodevalue(value)
Skip Montanaro289bc052007-08-17 02:30:27 +0000570 self.putenv(key, value)
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000571 self._data[key] = value
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000572
Skip Montanaro289bc052007-08-17 02:30:27 +0000573 def __delitem__(self, key):
Victor Stinner84ae1182010-05-06 22:05:07 +0000574 key = self.encodekey(key)
Skip Montanaro289bc052007-08-17 02:30:27 +0000575 self.unsetenv(key)
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000576 del self._data[key]
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000577
Skip Montanaro289bc052007-08-17 02:30:27 +0000578 def __iter__(self):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000579 for key in self._data:
Victor Stinner84ae1182010-05-06 22:05:07 +0000580 yield self.decodekey(key)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000581
Skip Montanaro289bc052007-08-17 02:30:27 +0000582 def __len__(self):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000583 return len(self._data)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000584
585 def __repr__(self):
Victor Stinnerbed71172010-07-28 21:25:42 +0000586 return 'environ({{{}}})'.format(', '.join(
Victor Stinnerd73c1a32010-07-28 21:23:23 +0000587 ('{!r}: {!r}'.format(self.decodekey(key), self.decodevalue(value))
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000588 for key, value in self._data.items())))
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000589
Skip Montanaro289bc052007-08-17 02:30:27 +0000590 def copy(self):
591 return dict(self)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000592
Skip Montanaro289bc052007-08-17 02:30:27 +0000593 def setdefault(self, key, value):
594 if key not in self:
595 self[key] = value
596 return self[key]
597
598try:
599 _putenv = putenv
600except NameError:
601 _putenv = lambda key, value: None
Martin v. Löwisa90f4382001-03-07 09:05:45 +0000602else:
Skip Montanaro289bc052007-08-17 02:30:27 +0000603 __all__.append("putenv")
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000604
Skip Montanaro289bc052007-08-17 02:30:27 +0000605try:
606 _unsetenv = unsetenv
607except NameError:
608 _unsetenv = lambda key: _putenv(key, "")
609else:
610 __all__.append("unsetenv")
Guido van Rossumc524d952001-10-19 01:31:59 +0000611
Victor Stinner84ae1182010-05-06 22:05:07 +0000612def _createenviron():
613 if name in ('os2', 'nt'):
614 # Where Env Var Names Must Be UPPERCASE
615 def check_str(value):
616 if not isinstance(value, str):
617 raise TypeError("str expected, not %s" % type(value).__name__)
618 return value
619 encode = check_str
620 decode = str
621 def encodekey(key):
622 return encode(key).upper()
623 data = {}
624 for key, value in environ.items():
625 data[encodekey(key)] = value
626 else:
627 # Where Env Var Names Can Be Mixed Case
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000628 encoding = sys.getfilesystemencoding()
Victor Stinner84ae1182010-05-06 22:05:07 +0000629 def encode(value):
630 if not isinstance(value, str):
631 raise TypeError("str expected, not %s" % type(value).__name__)
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000632 return value.encode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000633 def decode(value):
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000634 return value.decode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000635 encodekey = encode
636 data = environ
637 return _Environ(data,
638 encodekey, decode,
639 encode, decode,
640 _putenv, _unsetenv)
Guido van Rossumc524d952001-10-19 01:31:59 +0000641
Victor Stinner84ae1182010-05-06 22:05:07 +0000642# unicode environ
643environ = _createenviron()
644del _createenviron
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000645
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000646
Jack Jansenb11ce9b2003-01-08 16:33:40 +0000647def getenv(key, default=None):
Tim Peters2c60f7a2003-01-29 03:49:43 +0000648 """Get an environment variable, return None if it doesn't exist.
Victor Stinner84ae1182010-05-06 22:05:07 +0000649 The optional second argument can specify an alternate default.
650 key, default and the result are str."""
Tim Peters2c60f7a2003-01-29 03:49:43 +0000651 return environ.get(key, default)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000652
Victor Stinnerb745a742010-05-18 17:17:23 +0000653supports_bytes_environ = name not in ('os2', 'nt')
654__all__.extend(("getenv", "supports_bytes_environ"))
655
656if supports_bytes_environ:
Victor Stinner84ae1182010-05-06 22:05:07 +0000657 def _check_bytes(value):
658 if not isinstance(value, bytes):
659 raise TypeError("bytes expected, not %s" % type(value).__name__)
660 return value
661
662 # bytes environ
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000663 environb = _Environ(environ._data,
Victor Stinner84ae1182010-05-06 22:05:07 +0000664 _check_bytes, bytes,
665 _check_bytes, bytes,
666 _putenv, _unsetenv)
667 del _check_bytes
668
669 def getenvb(key, default=None):
670 """Get an environment variable, return None if it doesn't exist.
671 The optional second argument can specify an alternate default.
672 key, default and the result are bytes."""
673 return environb.get(key, default)
Victor Stinner70120e22010-07-29 17:19:38 +0000674
675 __all__.extend(("environb", "getenvb"))
Victor Stinner84ae1182010-05-06 22:05:07 +0000676
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000677def _fscodec():
678 encoding = sys.getfilesystemencoding()
679 if encoding == 'mbcs':
Victor Stinnere882aac2010-10-24 21:12:26 +0000680 errors = 'strict'
Victor Stinner313a1202010-06-11 23:56:51 +0000681 else:
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000682 errors = 'surrogateescape'
Victor Stinnere8d51452010-08-19 01:05:19 +0000683
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000684 def fsencode(filename):
685 """
686 Encode filename to the filesystem encoding with 'surrogateescape' error
687 handler, return bytes unchanged. On Windows, use 'strict' error handler if
688 the file system encoding is 'mbcs' (which is the default encoding).
689 """
690 if isinstance(filename, bytes):
691 return filename
692 elif isinstance(filename, str):
693 return filename.encode(encoding, errors)
Victor Stinnere8d51452010-08-19 01:05:19 +0000694 else:
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000695 raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
696
697 def fsdecode(filename):
698 """
699 Decode filename from the filesystem encoding with 'surrogateescape' error
700 handler, return str unchanged. On Windows, use 'strict' error handler if
701 the file system encoding is 'mbcs' (which is the default encoding).
702 """
703 if isinstance(filename, str):
704 return filename
705 elif isinstance(filename, bytes):
706 return filename.decode(encoding, errors)
707 else:
708 raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
709
710 return fsencode, fsdecode
711
712fsencode, fsdecode = _fscodec()
713del _fscodec
Victor Stinner449c4662010-05-08 11:10:09 +0000714
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000715# Supply spawn*() (probably only for Unix)
716if _exists("fork") and not _exists("spawnv") and _exists("execv"):
717
718 P_WAIT = 0
719 P_NOWAIT = P_NOWAITO = 1
720
Petri Lehtinen3bc37f22012-05-23 21:36:16 +0300721 __all__.extend(["P_WAIT", "P_NOWAIT", "P_NOWAITO"])
722
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000723 # XXX Should we support P_DETACH? I suppose it could fork()**2
724 # and close the std I/O streams. Also, P_OVERLAY is the same
725 # as execv*()?
726
727 def _spawnvef(mode, file, args, env, func):
728 # Internal helper; func is the exec*() function to use
729 pid = fork()
730 if not pid:
731 # Child
732 try:
733 if env is None:
734 func(file, args)
735 else:
736 func(file, args, env)
737 except:
738 _exit(127)
739 else:
740 # Parent
741 if mode == P_NOWAIT:
742 return pid # Caller is responsible for waiting!
743 while 1:
744 wpid, sts = waitpid(pid, 0)
745 if WIFSTOPPED(sts):
746 continue
747 elif WIFSIGNALED(sts):
748 return -WTERMSIG(sts)
749 elif WIFEXITED(sts):
750 return WEXITSTATUS(sts)
751 else:
Collin Winter828f04a2007-08-31 00:04:24 +0000752 raise error("Not stopped, signaled or exited???")
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000753
754 def spawnv(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000755 """spawnv(mode, file, args) -> integer
756
757Execute file with arguments from args in a subprocess.
758If mode == P_NOWAIT return the pid of the process.
759If mode == P_WAIT return the process's exit code if it exits normally;
Tim Peters2344fae2001-01-15 00:50:52 +0000760otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000761 return _spawnvef(mode, file, args, None, execv)
762
763 def spawnve(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000764 """spawnve(mode, file, args, env) -> integer
765
766Execute file with arguments from args in a subprocess with the
767specified environment.
768If mode == P_NOWAIT return the pid of the process.
769If mode == P_WAIT return the process's exit code if it exits normally;
770otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000771 return _spawnvef(mode, file, args, env, execve)
772
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000773 # Note: spawnvp[e] is't currently supported on Windows
774
775 def spawnvp(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000776 """spawnvp(mode, file, args) -> integer
777
778Execute file (which is looked for along $PATH) with arguments from
779args in a subprocess.
780If mode == P_NOWAIT return the pid of the process.
781If mode == P_WAIT return the process's exit code if it exits normally;
782otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000783 return _spawnvef(mode, file, args, None, execvp)
784
785 def spawnvpe(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000786 """spawnvpe(mode, file, args, env) -> integer
787
788Execute file (which is looked for along $PATH) with arguments from
789args in a subprocess with the supplied environment.
790If mode == P_NOWAIT return the pid of the process.
791If mode == P_WAIT return the process's exit code if it exits normally;
792otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000793 return _spawnvef(mode, file, args, env, execvpe)
794
795if _exists("spawnv"):
796 # These aren't supplied by the basic Windows code
797 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000798
799 def spawnl(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000800 """spawnl(mode, file, *args) -> integer
801
802Execute file with arguments from args in a subprocess.
803If mode == P_NOWAIT return the pid of the process.
804If mode == P_WAIT return the process's exit code if it exits normally;
805otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000806 return spawnv(mode, file, args)
807
808 def spawnle(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000809 """spawnle(mode, file, *args, env) -> integer
810
811Execute file with arguments from args in a subprocess with the
812supplied environment.
813If mode == P_NOWAIT return the pid of the process.
814If mode == P_WAIT return the process's exit code if it exits normally;
815otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000816 env = args[-1]
817 return spawnve(mode, file, args[:-1], env)
818
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000819
820 __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
821
822
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000823if _exists("spawnvp"):
824 # At the moment, Windows doesn't implement spawnvp[e],
825 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000826 def spawnlp(mode, file, *args):
Neal Norwitzb7f68102003-07-02 02:49:33 +0000827 """spawnlp(mode, file, *args) -> integer
Guido van Rossume0cd2912000-04-21 18:35:36 +0000828
829Execute file (which is looked for along $PATH) with arguments from
830args in a subprocess with the supplied environment.
831If mode == P_NOWAIT return the pid of the process.
832If mode == P_WAIT return the process's exit code if it exits normally;
833otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000834 return spawnvp(mode, file, args)
835
836 def spawnlpe(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000837 """spawnlpe(mode, file, *args, env) -> integer
838
839Execute file (which is looked for along $PATH) with arguments from
840args in a subprocess with the supplied environment.
841If mode == P_NOWAIT return the pid of the process.
842If mode == P_WAIT return the process's exit code if it exits normally;
843otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000844 env = args[-1]
845 return spawnvpe(mode, file, args[:-1], env)
Guido van Rossume0cd2912000-04-21 18:35:36 +0000846
847
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000848 __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
Skip Montanaro269b83b2001-02-06 01:07:02 +0000849
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000850import copyreg as _copyreg
Michael W. Hudson0e025302002-03-06 17:11:18 +0000851
852def _make_stat_result(tup, dict):
853 return stat_result(tup, dict)
854
855def _pickle_stat_result(sr):
856 (type, args) = sr.__reduce__()
857 return (_make_stat_result, args)
858
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000859try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000860 _copyreg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000861except NameError: # stat_result may not exist
862 pass
Michael W. Hudson0e025302002-03-06 17:11:18 +0000863
864def _make_statvfs_result(tup, dict):
865 return statvfs_result(tup, dict)
866
867def _pickle_statvfs_result(sr):
868 (type, args) = sr.__reduce__()
869 return (_make_statvfs_result, args)
870
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000871try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000872 _copyreg.pickle(statvfs_result, _pickle_statvfs_result,
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000873 _make_statvfs_result)
Michael W. Hudsone5363b72002-03-15 10:21:59 +0000874except NameError: # statvfs_result may not exist
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000875 pass
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000876
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000877# Supply os.popen()
Antoine Pitrou877766d2011-03-19 17:00:37 +0100878def popen(cmd, mode="r", buffering=-1):
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000879 if not isinstance(cmd, str):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000880 raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
881 if mode not in ("r", "w"):
882 raise ValueError("invalid mode %r" % mode)
Antoine Pitrou877766d2011-03-19 17:00:37 +0100883 if buffering == 0 or buffering == None:
884 raise ValueError("popen() does not support unbuffered streams")
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000885 import subprocess, io
886 if mode == "r":
887 proc = subprocess.Popen(cmd,
888 shell=True,
889 stdout=subprocess.PIPE,
890 bufsize=buffering)
891 return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
892 else:
893 proc = subprocess.Popen(cmd,
894 shell=True,
895 stdin=subprocess.PIPE,
896 bufsize=buffering)
897 return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
898
899# Helper for popen() -- a proxy for a file whose close waits for the process
900class _wrap_close:
901 def __init__(self, stream, proc):
902 self._stream = stream
903 self._proc = proc
904 def close(self):
905 self._stream.close()
Amaury Forgeot d'Arc97e5f282009-07-11 09:35:13 +0000906 returncode = self._proc.wait()
907 if returncode == 0:
908 return None
909 if name == 'nt':
910 return returncode
911 else:
912 return returncode << 8 # Shift left to match old behavior
Antoine Pitrouac625352009-12-09 00:01:27 +0000913 def __enter__(self):
914 return self
915 def __exit__(self, *args):
916 self.close()
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000917 def __getattr__(self, name):
918 return getattr(self._stream, name)
Thomas Heller476157b2007-09-04 11:27:47 +0000919 def __iter__(self):
920 return iter(self._stream)
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000921
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +0000922# Supply os.fdopen()
923def fdopen(fd, *args, **kwargs):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000924 if not isinstance(fd, int):
925 raise TypeError("invalid fd type (%s, expected integer)" % type(fd))
926 import io
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +0000927 return io.open(fd, *args, **kwargs)