blob: 11e4d60d15ec9844f6f5a0e425d8851498fbe2f0 [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
124SEEK_SET = 0
125SEEK_CUR = 1
126SEEK_END = 2
127
Terry Reedy5a22b652010-12-02 07:05:56 +0000128
129def _get_masked_mode(mode):
130 mask = umask(0)
131 umask(mask)
132 return mode & ~mask
133
Guido van Rossum4def7de1998-07-24 20:48:03 +0000134# Super directory utilities.
135# (Inspired by Eric Raymond; the doc strings are mostly his)
136
Terry Reedy5a22b652010-12-02 07:05:56 +0000137def makedirs(name, mode=0o777, exist_ok=False):
138 """makedirs(path [, mode=0o777][, exist_ok=False])
Guido van Rossum4def7de1998-07-24 20:48:03 +0000139
140 Super-mkdir; create a leaf directory and all intermediate ones.
141 Works like mkdir, except that any intermediate path segment (not
Terry Reedy5a22b652010-12-02 07:05:56 +0000142 just the rightmost) will be created if it does not exist. If the
143 target directory with the same mode as we specified already exists,
144 raises an OSError if exist_ok is False, otherwise no exception is
145 raised. This is recursive.
Guido van Rossum4def7de1998-07-24 20:48:03 +0000146
147 """
148 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000149 if not tail:
150 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000151 if head and tail and not path.exists(head):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000152 try:
Terry Reedy5a22b652010-12-02 07:05:56 +0000153 makedirs(head, mode, exist_ok)
Guido van Rossumb940e112007-01-10 16:19:56 +0000154 except OSError as e:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000155 # be happy if someone already created the path
Christian Heimes45f9af32007-11-27 21:50:00 +0000156 if e.errno != errno.EEXIST:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000157 raise
Andrew M. Kuchling6fccc8a2003-12-23 16:33:28 +0000158 if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists
159 return
Terry Reedy5a22b652010-12-02 07:05:56 +0000160 try:
161 mkdir(name, mode)
162 except OSError as e:
Gregory P. Smitha81c8562012-06-03 14:30:44 -0700163 dir_exists = path.isdir(name)
164 expected_mode = _get_masked_mode(mode)
165 if dir_exists:
166 # S_ISGID is automatically copied by the OS from parent to child
167 # directories on mkdir. Don't consider it being set to be a mode
168 # mismatch as mkdir does not unset it when not specified in mode.
169 actual_mode = st.S_IMODE(lstat(name).st_mode) & ~st.S_ISGID
170 else:
171 actual_mode = -1
172 if not (e.errno == errno.EEXIST and exist_ok and dir_exists and
173 actual_mode == expected_mode):
174 if dir_exists and actual_mode != expected_mode:
175 e.strerror += ' (mode %o != expected mode %o)' % (
176 actual_mode, expected_mode)
Terry Reedy5a22b652010-12-02 07:05:56 +0000177 raise
Guido van Rossum4def7de1998-07-24 20:48:03 +0000178
179def removedirs(name):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000180 """removedirs(path)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000181
Fredrik Lundh96c1c7a2005-11-12 15:55:04 +0000182 Super-rmdir; remove a leaf directory and all empty intermediate
Guido van Rossum4def7de1998-07-24 20:48:03 +0000183 ones. Works like rmdir except that, if the leaf directory is
184 successfully removed, directories corresponding to rightmost path
Tim Petersc4e09402003-04-25 07:11:48 +0000185 segments will be pruned away until either the whole path is
Guido van Rossum4def7de1998-07-24 20:48:03 +0000186 consumed or an error occurs. Errors during this latter phase are
187 ignored -- they generally mean that a directory was not empty.
188
189 """
190 rmdir(name)
191 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000192 if not tail:
193 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000194 while head and tail:
195 try:
196 rmdir(head)
197 except error:
198 break
199 head, tail = path.split(head)
200
201def renames(old, new):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000202 """renames(old, new)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000203
204 Super-rename; create directories as necessary and delete any left
205 empty. Works like rename, except creation of any intermediate
206 directories needed to make the new pathname good is attempted
207 first. After the rename, directories corresponding to rightmost
208 path segments of the old name will be pruned way until either the
209 whole path is consumed or a nonempty directory is found.
210
211 Note: this function can fail with the new directory structure made
212 if you lack permissions needed to unlink the leaf directory or
213 file.
214
215 """
216 head, tail = path.split(new)
217 if head and tail and not path.exists(head):
218 makedirs(head)
219 rename(old, new)
220 head, tail = path.split(old)
221 if head and tail:
222 try:
223 removedirs(head)
224 except error:
225 pass
226
Skip Montanaro269b83b2001-02-06 01:07:02 +0000227__all__.extend(["makedirs", "removedirs", "renames"])
228
Guido van Rossumd8faa362007-04-27 19:54:29 +0000229def walk(top, topdown=True, onerror=None, followlinks=False):
Tim Petersc4e09402003-04-25 07:11:48 +0000230 """Directory tree generator.
231
232 For each directory in the directory tree rooted at top (including top
233 itself, but excluding '.' and '..'), yields a 3-tuple
234
235 dirpath, dirnames, filenames
236
237 dirpath is a string, the path to the directory. dirnames is a list of
238 the names of the subdirectories in dirpath (excluding '.' and '..').
239 filenames is a list of the names of the non-directory files in dirpath.
240 Note that the names in the lists are just names, with no path components.
241 To get a full path (which begins with top) to a file or directory in
242 dirpath, do os.path.join(dirpath, name).
243
244 If optional arg 'topdown' is true or not specified, the triple for a
245 directory is generated before the triples for any of its subdirectories
246 (directories are generated top down). If topdown is false, the triple
247 for a directory is generated after the triples for all of its
248 subdirectories (directories are generated bottom up).
249
250 When topdown is true, the caller can modify the dirnames list in-place
251 (e.g., via del or slice assignment), and walk will only recurse into the
252 subdirectories whose names remain in dirnames; this can be used to prune
253 the search, or to impose a specific order of visiting. Modifying
254 dirnames when topdown is false is ineffective, since the directories in
255 dirnames have already been generated by the time dirnames itself is
256 generated.
257
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000258 By default errors from the os.listdir() call are ignored. If
259 optional arg 'onerror' is specified, it should be a function; it
260 will be called with one argument, an os.error instance. It can
261 report the error to continue with the walk, or raise the exception
262 to abort the walk. Note that the filename is available as the
263 filename attribute of the exception object.
264
Guido van Rossumd8faa362007-04-27 19:54:29 +0000265 By default, os.walk does not follow symbolic links to subdirectories on
266 systems that support them. In order to get this functionality, set the
267 optional argument 'followlinks' to true.
268
Tim Petersc4e09402003-04-25 07:11:48 +0000269 Caution: if you pass a relative pathname for top, don't change the
270 current working directory between resumptions of walk. walk never
271 changes the current directory, and assumes that the client doesn't
272 either.
273
274 Example:
275
Christian Heimes5d8da202008-05-06 13:58:24 +0000276 import os
Tim Petersc4e09402003-04-25 07:11:48 +0000277 from os.path import join, getsize
Christian Heimes5d8da202008-05-06 13:58:24 +0000278 for root, dirs, files in os.walk('python/Lib/email'):
Neal Norwitz752abd02008-05-13 04:55:24 +0000279 print(root, "consumes", end="")
280 print(sum([getsize(join(root, name)) for name in files]), end="")
281 print("bytes in", len(files), "non-directory files")
Tim Petersc4e09402003-04-25 07:11:48 +0000282 if 'CVS' in dirs:
283 dirs.remove('CVS') # don't visit CVS directories
284 """
285
Benjamin Petersonf6489f92009-11-25 17:46:26 +0000286 islink, join, isdir = path.islink, path.join, path.isdir
Tim Petersc4e09402003-04-25 07:11:48 +0000287
288 # We may not have read permission for top, in which case we can't
Alexandre Vassalotti4e6531e2008-05-09 20:00:17 +0000289 # get a list of the files the directory contains. os.walk
Tim Petersc4e09402003-04-25 07:11:48 +0000290 # always suppressed the exception then, rather than blow up for a
291 # minor reason when (say) a thousand readable directories are still
292 # left to visit. That logic is copied here.
293 try:
294 # Note that listdir and error are globals in this module due
295 # to earlier import-*.
296 names = listdir(top)
Guido van Rossumb940e112007-01-10 16:19:56 +0000297 except error as err:
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000298 if onerror is not None:
299 onerror(err)
Tim Petersc4e09402003-04-25 07:11:48 +0000300 return
301
302 dirs, nondirs = [], []
303 for name in names:
304 if isdir(join(top, name)):
305 dirs.append(name)
306 else:
307 nondirs.append(name)
308
309 if topdown:
310 yield top, dirs, nondirs
311 for name in dirs:
Benjamin Petersonf6489f92009-11-25 17:46:26 +0000312 new_path = join(top, name)
313 if followlinks or not islink(new_path):
Benjamin Peterson569d0872012-05-10 16:17:35 -0500314 yield from walk(new_path, topdown, onerror, followlinks)
Tim Petersc4e09402003-04-25 07:11:48 +0000315 if not topdown:
316 yield top, dirs, nondirs
317
318__all__.append("walk")
319
Charles-François Natali7372b062012-02-05 15:15:38 +0100320if _exists("openat"):
321
322 def fwalk(top, topdown=True, onerror=None, followlinks=False):
323 """Directory tree generator.
324
325 This behaves exactly like walk(), except that it yields a 4-tuple
326
327 dirpath, dirnames, filenames, dirfd
328
329 `dirpath`, `dirnames` and `filenames` are identical to walk() output,
330 and `dirfd` is a file descriptor referring to the directory `dirpath`.
331
332 The advantage of walkfd() over walk() is that it's safe against symlink
333 races (when followlinks is False).
334
335 Caution:
336 Since fwalk() yields file descriptors, those are only valid until the
337 next iteration step, so you should dup() them if you want to keep them
338 for a longer period.
339
340 Example:
341
342 import os
343 for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
344 print(root, "consumes", end="")
345 print(sum([os.fstatat(rootfd, name).st_size for name in files]),
346 end="")
347 print("bytes in", len(files), "non-directory files")
348 if 'CVS' in dirs:
349 dirs.remove('CVS') # don't visit CVS directories
350 """
351 # Note: To guard against symlink races, we use the standard
352 # lstat()/open()/fstat() trick.
353 orig_st = lstat(top)
354 topfd = open(top, O_RDONLY)
355 try:
356 if (followlinks or (st.S_ISDIR(orig_st.st_mode) and
Charles-François Natali84c0ca02012-04-22 15:55:43 +0200357 path.samestat(orig_st, fstat(topfd)))):
Benjamin Peterson569d0872012-05-10 16:17:35 -0500358 yield from _fwalk(topfd, top, topdown, onerror, followlinks)
Charles-François Natali7372b062012-02-05 15:15:38 +0100359 finally:
360 close(topfd)
361
362 def _fwalk(topfd, toppath, topdown, onerror, followlinks):
363 # Note: This uses O(depth of the directory tree) file descriptors: if
364 # necessary, it can be adapted to only require O(1) FDs, see issue
365 # #13734.
366
367 # whether to follow symlinks
368 flag = 0 if followlinks else AT_SYMLINK_NOFOLLOW
369
Charles-François Natali77940902012-02-06 19:54:48 +0100370 names = flistdir(topfd)
Charles-François Natali7372b062012-02-05 15:15:38 +0100371 dirs, nondirs = [], []
372 for name in names:
Hynek Schlawack66bfcc12012-05-15 16:32:21 +0200373 try:
374 # Here, we don't use AT_SYMLINK_NOFOLLOW to be consistent with
375 # walk() which reports symlinks to directories as directories.
376 # We do however check for symlinks before recursing into
377 # a subdirectory.
378 if st.S_ISDIR(fstatat(topfd, name).st_mode):
379 dirs.append(name)
380 else:
381 nondirs.append(name)
382 except FileNotFoundError:
383 try:
384 # Add dangling symlinks, ignore disappeared files
385 if st.S_ISLNK(fstatat(topfd, name, AT_SYMLINK_NOFOLLOW)
386 .st_mode):
387 nondirs.append(name)
388 except FileNotFoundError:
389 continue
Charles-François Natali7372b062012-02-05 15:15:38 +0100390
391 if topdown:
392 yield toppath, dirs, nondirs, topfd
393
394 for name in dirs:
395 try:
396 orig_st = fstatat(topfd, name, flag)
397 dirfd = openat(topfd, name, O_RDONLY)
398 except error as err:
399 if onerror is not None:
400 onerror(err)
401 return
402 try:
Charles-François Natali84c0ca02012-04-22 15:55:43 +0200403 if followlinks or path.samestat(orig_st, fstat(dirfd)):
Charles-François Natali7372b062012-02-05 15:15:38 +0100404 dirpath = path.join(toppath, name)
Benjamin Peterson569d0872012-05-10 16:17:35 -0500405 yield from _fwalk(dirfd, dirpath, topdown, onerror, followlinks)
Charles-François Natali7372b062012-02-05 15:15:38 +0100406 finally:
407 close(dirfd)
408
409 if not topdown:
410 yield toppath, dirs, nondirs, topfd
411
412 __all__.append("fwalk")
413
Guido van Rossuma28dab51997-08-29 22:36:47 +0000414# Make sure os.environ exists, at least
415try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000416 environ
Guido van Rossuma28dab51997-08-29 22:36:47 +0000417except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000418 environ = {}
Guido van Rossuma28dab51997-08-29 22:36:47 +0000419
Guido van Rossume65cce51993-11-08 15:05:21 +0000420def execl(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000421 """execl(file, *args)
422
423 Execute the executable file with argument list args, replacing the
424 current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000425 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000426
427def execle(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000428 """execle(file, *args, env)
429
430 Execute the executable file with argument list args and
431 environment env, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000432 env = args[-1]
433 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000434
435def execlp(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000436 """execlp(file, *args)
437
438 Execute the executable file (which is searched for along $PATH)
439 with argument list args, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000440 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000441
Guido van Rossum030afb11995-03-14 17:27:18 +0000442def execlpe(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000443 """execlpe(file, *args, env)
444
445 Execute the executable file (which is searched for along $PATH)
446 with argument list args and environment env, replacing the current
Tim Peters2344fae2001-01-15 00:50:52 +0000447 process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000448 env = args[-1]
449 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000450
Guido van Rossume65cce51993-11-08 15:05:21 +0000451def execvp(file, args):
Matthias Klosea09c54f2010-01-31 16:48:44 +0000452 """execvp(file, args)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000453
454 Execute the executable file (which is searched for along $PATH)
455 with argument list args, replacing the current process.
Thomas Wouters7e474022000-07-16 12:04:32 +0000456 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000457 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000458
459def execvpe(file, args, env):
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000460 """execvpe(file, args, env)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000461
462 Execute the executable file (which is searched for along $PATH)
463 with argument list args and environment env , replacing the
464 current process.
Tim Peters2344fae2001-01-15 00:50:52 +0000465 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000466 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000467
Skip Montanaro269b83b2001-02-06 01:07:02 +0000468__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
469
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000470def _execvpe(file, args, env=None):
471 if env is not None:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000472 exec_func = execve
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000473 argrest = (args, env)
474 else:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000475 exec_func = execv
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000476 argrest = (args,)
477 env = environ
Guido van Rossumaed51d82002-08-05 16:13:24 +0000478
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000479 head, tail = path.split(file)
480 if head:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000481 exec_func(file, *argrest)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000482 return
Guido van Rossume7ba4952007-06-06 23:52:48 +0000483 last_exc = saved_exc = None
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000484 saved_tb = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000485 path_list = get_exec_path(env)
486 if name != 'nt':
487 file = fsencode(file)
488 path_list = map(fsencode, path_list)
489 for dir in path_list:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000490 fullname = path.join(dir, file)
491 try:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000492 exec_func(fullname, *argrest)
Guido van Rossumb940e112007-01-10 16:19:56 +0000493 except error as e:
Guido van Rossume7ba4952007-06-06 23:52:48 +0000494 last_exc = e
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000495 tb = sys.exc_info()[2]
Christian Heimes45f9af32007-11-27 21:50:00 +0000496 if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000497 and saved_exc is None):
498 saved_exc = e
499 saved_tb = tb
500 if saved_exc:
Benjamin Peterson4b068192009-02-20 03:19:25 +0000501 raise saved_exc.with_traceback(saved_tb)
502 raise last_exc.with_traceback(tb)
Guido van Rossumd74fb6b2001-03-02 06:43:49 +0000503
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000504
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000505def get_exec_path(env=None):
506 """Returns the sequence of directories that will be searched for the
507 named executable (similar to a shell) when launching a process.
508
509 *env* must be an environment variable dict or None. If *env* is None,
510 os.environ will be used.
511 """
Victor Stinner273b7662010-11-06 12:59:33 +0000512 # Use a local import instead of a global import to limit the number of
513 # modules loaded at startup: the os module is always loaded at startup by
514 # Python. It may also avoid a bootstrap issue.
Victor Stinner6f35eda2010-10-29 00:38:58 +0000515 import warnings
516
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000517 if env is None:
518 env = environ
Victor Stinnerb745a742010-05-18 17:17:23 +0000519
Victor Stinnerbb4f2182010-11-07 15:43:39 +0000520 # {b'PATH': ...}.get('PATH') and {'PATH': ...}.get(b'PATH') emit a
521 # BytesWarning when using python -b or python -bb: ignore the warning
Victor Stinner273b7662010-11-06 12:59:33 +0000522 with warnings.catch_warnings():
523 warnings.simplefilter("ignore", BytesWarning)
Victor Stinnerb745a742010-05-18 17:17:23 +0000524
Victor Stinnerb745a742010-05-18 17:17:23 +0000525 try:
Victor Stinner273b7662010-11-06 12:59:33 +0000526 path_list = env.get('PATH')
527 except TypeError:
528 path_list = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000529
Victor Stinner273b7662010-11-06 12:59:33 +0000530 if supports_bytes_environ:
531 try:
532 path_listb = env[b'PATH']
533 except (KeyError, TypeError):
534 pass
535 else:
536 if path_list is not None:
537 raise ValueError(
538 "env cannot contain 'PATH' and b'PATH' keys")
539 path_list = path_listb
540
541 if path_list is not None and isinstance(path_list, bytes):
542 path_list = fsdecode(path_list)
Victor Stinnerb745a742010-05-18 17:17:23 +0000543
544 if path_list is None:
545 path_list = defpath
546 return path_list.split(pathsep)
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000547
548
Skip Montanaro289bc052007-08-17 02:30:27 +0000549# Change environ to automatically call putenv(), unsetenv if they exist.
Raymond Hettinger158c9c22011-02-22 00:41:50 +0000550from collections.abc import MutableMapping
Skip Montanaro289bc052007-08-17 02:30:27 +0000551
552class _Environ(MutableMapping):
Victor Stinner84ae1182010-05-06 22:05:07 +0000553 def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue, putenv, unsetenv):
554 self.encodekey = encodekey
555 self.decodekey = decodekey
556 self.encodevalue = encodevalue
557 self.decodevalue = decodevalue
Skip Montanaro289bc052007-08-17 02:30:27 +0000558 self.putenv = putenv
559 self.unsetenv = unsetenv
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000560 self._data = data
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000561
Skip Montanaro289bc052007-08-17 02:30:27 +0000562 def __getitem__(self, key):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000563 value = self._data[self.encodekey(key)]
Victor Stinner84ae1182010-05-06 22:05:07 +0000564 return self.decodevalue(value)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000565
Skip Montanaro289bc052007-08-17 02:30:27 +0000566 def __setitem__(self, key, value):
Victor Stinner84ae1182010-05-06 22:05:07 +0000567 key = self.encodekey(key)
568 value = self.encodevalue(value)
Skip Montanaro289bc052007-08-17 02:30:27 +0000569 self.putenv(key, value)
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000570 self._data[key] = value
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000571
Skip Montanaro289bc052007-08-17 02:30:27 +0000572 def __delitem__(self, key):
Victor Stinner84ae1182010-05-06 22:05:07 +0000573 key = self.encodekey(key)
Skip Montanaro289bc052007-08-17 02:30:27 +0000574 self.unsetenv(key)
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000575 del self._data[key]
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000576
Skip Montanaro289bc052007-08-17 02:30:27 +0000577 def __iter__(self):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000578 for key in self._data:
Victor Stinner84ae1182010-05-06 22:05:07 +0000579 yield self.decodekey(key)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000580
Skip Montanaro289bc052007-08-17 02:30:27 +0000581 def __len__(self):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000582 return len(self._data)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000583
584 def __repr__(self):
Victor Stinnerbed71172010-07-28 21:25:42 +0000585 return 'environ({{{}}})'.format(', '.join(
Victor Stinnerd73c1a32010-07-28 21:23:23 +0000586 ('{!r}: {!r}'.format(self.decodekey(key), self.decodevalue(value))
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000587 for key, value in self._data.items())))
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000588
Skip Montanaro289bc052007-08-17 02:30:27 +0000589 def copy(self):
590 return dict(self)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000591
Skip Montanaro289bc052007-08-17 02:30:27 +0000592 def setdefault(self, key, value):
593 if key not in self:
594 self[key] = value
595 return self[key]
596
597try:
598 _putenv = putenv
599except NameError:
600 _putenv = lambda key, value: None
Martin v. Löwisa90f4382001-03-07 09:05:45 +0000601else:
Skip Montanaro289bc052007-08-17 02:30:27 +0000602 __all__.append("putenv")
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000603
Skip Montanaro289bc052007-08-17 02:30:27 +0000604try:
605 _unsetenv = unsetenv
606except NameError:
607 _unsetenv = lambda key: _putenv(key, "")
608else:
609 __all__.append("unsetenv")
Guido van Rossumc524d952001-10-19 01:31:59 +0000610
Victor Stinner84ae1182010-05-06 22:05:07 +0000611def _createenviron():
612 if name in ('os2', 'nt'):
613 # Where Env Var Names Must Be UPPERCASE
614 def check_str(value):
615 if not isinstance(value, str):
616 raise TypeError("str expected, not %s" % type(value).__name__)
617 return value
618 encode = check_str
619 decode = str
620 def encodekey(key):
621 return encode(key).upper()
622 data = {}
623 for key, value in environ.items():
624 data[encodekey(key)] = value
625 else:
626 # Where Env Var Names Can Be Mixed Case
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000627 encoding = sys.getfilesystemencoding()
Victor Stinner84ae1182010-05-06 22:05:07 +0000628 def encode(value):
629 if not isinstance(value, str):
630 raise TypeError("str expected, not %s" % type(value).__name__)
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000631 return value.encode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000632 def decode(value):
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000633 return value.decode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000634 encodekey = encode
635 data = environ
636 return _Environ(data,
637 encodekey, decode,
638 encode, decode,
639 _putenv, _unsetenv)
Guido van Rossumc524d952001-10-19 01:31:59 +0000640
Victor Stinner84ae1182010-05-06 22:05:07 +0000641# unicode environ
642environ = _createenviron()
643del _createenviron
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000644
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000645
Jack Jansenb11ce9b2003-01-08 16:33:40 +0000646def getenv(key, default=None):
Tim Peters2c60f7a2003-01-29 03:49:43 +0000647 """Get an environment variable, return None if it doesn't exist.
Victor Stinner84ae1182010-05-06 22:05:07 +0000648 The optional second argument can specify an alternate default.
649 key, default and the result are str."""
Tim Peters2c60f7a2003-01-29 03:49:43 +0000650 return environ.get(key, default)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000651
Victor Stinnerb745a742010-05-18 17:17:23 +0000652supports_bytes_environ = name not in ('os2', 'nt')
653__all__.extend(("getenv", "supports_bytes_environ"))
654
655if supports_bytes_environ:
Victor Stinner84ae1182010-05-06 22:05:07 +0000656 def _check_bytes(value):
657 if not isinstance(value, bytes):
658 raise TypeError("bytes expected, not %s" % type(value).__name__)
659 return value
660
661 # bytes environ
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000662 environb = _Environ(environ._data,
Victor Stinner84ae1182010-05-06 22:05:07 +0000663 _check_bytes, bytes,
664 _check_bytes, bytes,
665 _putenv, _unsetenv)
666 del _check_bytes
667
668 def getenvb(key, default=None):
669 """Get an environment variable, return None if it doesn't exist.
670 The optional second argument can specify an alternate default.
671 key, default and the result are bytes."""
672 return environb.get(key, default)
Victor Stinner70120e22010-07-29 17:19:38 +0000673
674 __all__.extend(("environb", "getenvb"))
Victor Stinner84ae1182010-05-06 22:05:07 +0000675
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000676def _fscodec():
677 encoding = sys.getfilesystemencoding()
678 if encoding == 'mbcs':
Victor Stinnere882aac2010-10-24 21:12:26 +0000679 errors = 'strict'
Victor Stinner313a1202010-06-11 23:56:51 +0000680 else:
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000681 errors = 'surrogateescape'
Victor Stinnere8d51452010-08-19 01:05:19 +0000682
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000683 def fsencode(filename):
684 """
685 Encode filename to the filesystem encoding with 'surrogateescape' error
686 handler, return bytes unchanged. On Windows, use 'strict' error handler if
687 the file system encoding is 'mbcs' (which is the default encoding).
688 """
689 if isinstance(filename, bytes):
690 return filename
691 elif isinstance(filename, str):
692 return filename.encode(encoding, errors)
Victor Stinnere8d51452010-08-19 01:05:19 +0000693 else:
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000694 raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
695
696 def fsdecode(filename):
697 """
698 Decode filename from the filesystem encoding with 'surrogateescape' error
699 handler, return str unchanged. On Windows, use 'strict' error handler if
700 the file system encoding is 'mbcs' (which is the default encoding).
701 """
702 if isinstance(filename, str):
703 return filename
704 elif isinstance(filename, bytes):
705 return filename.decode(encoding, errors)
706 else:
707 raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
708
709 return fsencode, fsdecode
710
711fsencode, fsdecode = _fscodec()
712del _fscodec
Victor Stinner449c4662010-05-08 11:10:09 +0000713
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000714# Supply spawn*() (probably only for Unix)
715if _exists("fork") and not _exists("spawnv") and _exists("execv"):
716
717 P_WAIT = 0
718 P_NOWAIT = P_NOWAITO = 1
719
Petri Lehtinen3bc37f22012-05-23 21:36:16 +0300720 __all__.extend(["P_WAIT", "P_NOWAIT", "P_NOWAITO"])
721
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000722 # XXX Should we support P_DETACH? I suppose it could fork()**2
723 # and close the std I/O streams. Also, P_OVERLAY is the same
724 # as execv*()?
725
726 def _spawnvef(mode, file, args, env, func):
727 # Internal helper; func is the exec*() function to use
728 pid = fork()
729 if not pid:
730 # Child
731 try:
732 if env is None:
733 func(file, args)
734 else:
735 func(file, args, env)
736 except:
737 _exit(127)
738 else:
739 # Parent
740 if mode == P_NOWAIT:
741 return pid # Caller is responsible for waiting!
742 while 1:
743 wpid, sts = waitpid(pid, 0)
744 if WIFSTOPPED(sts):
745 continue
746 elif WIFSIGNALED(sts):
747 return -WTERMSIG(sts)
748 elif WIFEXITED(sts):
749 return WEXITSTATUS(sts)
750 else:
Collin Winter828f04a2007-08-31 00:04:24 +0000751 raise error("Not stopped, signaled or exited???")
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000752
753 def spawnv(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000754 """spawnv(mode, file, args) -> integer
755
756Execute file with arguments from args in a subprocess.
757If mode == P_NOWAIT return the pid of the process.
758If mode == P_WAIT return the process's exit code if it exits normally;
Tim Peters2344fae2001-01-15 00:50:52 +0000759otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000760 return _spawnvef(mode, file, args, None, execv)
761
762 def spawnve(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000763 """spawnve(mode, file, args, env) -> integer
764
765Execute file with arguments from args in a subprocess with the
766specified environment.
767If mode == P_NOWAIT return the pid of the process.
768If mode == P_WAIT return the process's exit code if it exits normally;
769otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000770 return _spawnvef(mode, file, args, env, execve)
771
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000772 # Note: spawnvp[e] is't currently supported on Windows
773
774 def spawnvp(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000775 """spawnvp(mode, file, args) -> integer
776
777Execute file (which is looked for along $PATH) with arguments from
778args in a subprocess.
779If mode == P_NOWAIT return the pid of the process.
780If mode == P_WAIT return the process's exit code if it exits normally;
781otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000782 return _spawnvef(mode, file, args, None, execvp)
783
784 def spawnvpe(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000785 """spawnvpe(mode, file, args, env) -> integer
786
787Execute file (which is looked for along $PATH) with arguments from
788args in a subprocess with the supplied environment.
789If mode == P_NOWAIT return the pid of the process.
790If mode == P_WAIT return the process's exit code if it exits normally;
791otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000792 return _spawnvef(mode, file, args, env, execvpe)
793
794if _exists("spawnv"):
795 # These aren't supplied by the basic Windows code
796 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000797
798 def spawnl(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000799 """spawnl(mode, file, *args) -> integer
800
801Execute file with arguments from args in a subprocess.
802If mode == P_NOWAIT return the pid of the process.
803If mode == P_WAIT return the process's exit code if it exits normally;
804otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000805 return spawnv(mode, file, args)
806
807 def spawnle(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000808 """spawnle(mode, file, *args, env) -> integer
809
810Execute file with arguments from args in a subprocess with the
811supplied environment.
812If mode == P_NOWAIT return the pid of the process.
813If mode == P_WAIT return the process's exit code if it exits normally;
814otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000815 env = args[-1]
816 return spawnve(mode, file, args[:-1], env)
817
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000818
819 __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
820
821
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000822if _exists("spawnvp"):
823 # At the moment, Windows doesn't implement spawnvp[e],
824 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000825 def spawnlp(mode, file, *args):
Neal Norwitzb7f68102003-07-02 02:49:33 +0000826 """spawnlp(mode, file, *args) -> integer
Guido van Rossume0cd2912000-04-21 18:35:36 +0000827
828Execute file (which is looked for along $PATH) with arguments from
829args in a subprocess with the supplied environment.
830If mode == P_NOWAIT return the pid of the process.
831If mode == P_WAIT return the process's exit code if it exits normally;
832otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000833 return spawnvp(mode, file, args)
834
835 def spawnlpe(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000836 """spawnlpe(mode, file, *args, env) -> integer
837
838Execute file (which is looked for along $PATH) with arguments from
839args in a subprocess with the supplied environment.
840If mode == P_NOWAIT return the pid of the process.
841If mode == P_WAIT return the process's exit code if it exits normally;
842otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000843 env = args[-1]
844 return spawnvpe(mode, file, args[:-1], env)
Guido van Rossume0cd2912000-04-21 18:35:36 +0000845
846
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000847 __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
Skip Montanaro269b83b2001-02-06 01:07:02 +0000848
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000849import copyreg as _copyreg
Michael W. Hudson0e025302002-03-06 17:11:18 +0000850
851def _make_stat_result(tup, dict):
852 return stat_result(tup, dict)
853
854def _pickle_stat_result(sr):
855 (type, args) = sr.__reduce__()
856 return (_make_stat_result, args)
857
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000858try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000859 _copyreg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000860except NameError: # stat_result may not exist
861 pass
Michael W. Hudson0e025302002-03-06 17:11:18 +0000862
863def _make_statvfs_result(tup, dict):
864 return statvfs_result(tup, dict)
865
866def _pickle_statvfs_result(sr):
867 (type, args) = sr.__reduce__()
868 return (_make_statvfs_result, args)
869
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000870try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000871 _copyreg.pickle(statvfs_result, _pickle_statvfs_result,
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000872 _make_statvfs_result)
Michael W. Hudsone5363b72002-03-15 10:21:59 +0000873except NameError: # statvfs_result may not exist
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000874 pass
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000875
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000876# Supply os.popen()
Antoine Pitrou877766d2011-03-19 17:00:37 +0100877def popen(cmd, mode="r", buffering=-1):
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000878 if not isinstance(cmd, str):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000879 raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
880 if mode not in ("r", "w"):
881 raise ValueError("invalid mode %r" % mode)
Antoine Pitrou877766d2011-03-19 17:00:37 +0100882 if buffering == 0 or buffering == None:
883 raise ValueError("popen() does not support unbuffered streams")
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000884 import subprocess, io
885 if mode == "r":
886 proc = subprocess.Popen(cmd,
887 shell=True,
888 stdout=subprocess.PIPE,
889 bufsize=buffering)
890 return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
891 else:
892 proc = subprocess.Popen(cmd,
893 shell=True,
894 stdin=subprocess.PIPE,
895 bufsize=buffering)
896 return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
897
898# Helper for popen() -- a proxy for a file whose close waits for the process
899class _wrap_close:
900 def __init__(self, stream, proc):
901 self._stream = stream
902 self._proc = proc
903 def close(self):
904 self._stream.close()
Amaury Forgeot d'Arc97e5f282009-07-11 09:35:13 +0000905 returncode = self._proc.wait()
906 if returncode == 0:
907 return None
908 if name == 'nt':
909 return returncode
910 else:
911 return returncode << 8 # Shift left to match old behavior
Antoine Pitrouac625352009-12-09 00:01:27 +0000912 def __enter__(self):
913 return self
914 def __exit__(self, *args):
915 self.close()
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000916 def __getattr__(self, name):
917 return getattr(self._stream, name)
Thomas Heller476157b2007-09-04 11:27:47 +0000918 def __iter__(self):
919 return iter(self._stream)
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000920
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +0000921# Supply os.fdopen()
922def fdopen(fd, *args, **kwargs):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000923 if not isinstance(fd, int):
924 raise TypeError("invalid fd type (%s, expected integer)" % type(fd))
925 import io
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +0000926 return io.open(fd, *args, **kwargs)