blob: 301870cb48731cf58fe61ef1e22d3fe74947b3ed [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",
Martin v. Löwis22b457e2005-01-16 08:40:58 +000033 "defpath", "name", "path", "devnull",
34 "SEEK_SET", "SEEK_CUR", "SEEK_END"]
Skip Montanaro269b83b2001-02-06 01:07:02 +000035
Charles-François Natali7372b062012-02-05 15:15:38 +010036def _exists(name):
37 return name in globals()
38
Skip Montanaro269b83b2001-02-06 01:07:02 +000039def _get_exports_list(module):
40 try:
41 return list(module.__all__)
42 except AttributeError:
43 return [n for n in dir(module) if n[0] != '_']
44
Guido van Rossuma28dab51997-08-29 22:36:47 +000045if 'posix' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000046 name = 'posix'
Guido van Rossume9387ea1998-05-22 15:26:04 +000047 linesep = '\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000048 from posix import *
49 try:
50 from posix import _exit
51 except ImportError:
52 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000053 import posixpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000054
Skip Montanaro269b83b2001-02-06 01:07:02 +000055 import posix
56 __all__.extend(_get_exports_list(posix))
57 del posix
58
Guido van Rossuma28dab51997-08-29 22:36:47 +000059elif 'nt' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000060 name = 'nt'
Guido van Rossume9387ea1998-05-22 15:26:04 +000061 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000062 from nt import *
Tim Peters6757c1e2003-01-08 21:20:57 +000063 try:
64 from nt import _exit
65 except ImportError:
66 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000067 import ntpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000068
Skip Montanaro269b83b2001-02-06 01:07:02 +000069 import nt
70 __all__.extend(_get_exports_list(nt))
71 del nt
72
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000073elif 'os2' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000074 name = 'os2'
Guido van Rossume9387ea1998-05-22 15:26:04 +000075 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000076 from os2 import *
77 try:
78 from os2 import _exit
79 except ImportError:
80 pass
Andrew MacIntyre5cef5712002-02-24 05:32:32 +000081 if sys.version.find('EMX GCC') == -1:
Skip Montanaro117910d2003-02-14 19:35:31 +000082 import ntpath as path
Andrew MacIntyre5cef5712002-02-24 05:32:32 +000083 else:
Skip Montanaro117910d2003-02-14 19:35:31 +000084 import os2emxpath as path
Andrew MacIntyre89f98652003-12-02 12:33:01 +000085 from _emx_link import link
Tim Petersf2715e02003-02-19 02:35:07 +000086
Skip Montanaro269b83b2001-02-06 01:07:02 +000087 import os2
88 __all__.extend(_get_exports_list(os2))
89 del os2
90
Guido van Rossum18df5d41999-06-11 01:37:27 +000091elif 'ce' in _names:
92 name = 'ce'
93 linesep = '\r\n'
Guido van Rossum18df5d41999-06-11 01:37:27 +000094 from ce import *
Tim Peters6757c1e2003-01-08 21:20:57 +000095 try:
96 from ce import _exit
97 except ImportError:
98 pass
Guido van Rossum18df5d41999-06-11 01:37:27 +000099 # We can use the standard Windows path.
Skip Montanaro117910d2003-02-14 19:35:31 +0000100 import ntpath as path
Tim Petersf2715e02003-02-19 02:35:07 +0000101
Skip Montanaro269b83b2001-02-06 01:07:02 +0000102 import ce
103 __all__.extend(_get_exports_list(ce))
104 del ce
105
Guido van Rossum2979b011994-08-01 11:18:30 +0000106else:
Collin Winter828f04a2007-08-31 00:04:24 +0000107 raise ImportError('no os specific module found')
Guido van Rossume65cce51993-11-08 15:05:21 +0000108
Skip Montanaro117910d2003-02-14 19:35:31 +0000109sys.modules['os.path'] = path
Georg Brandled5b9b32008-12-05 07:45:54 +0000110from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
111 devnull)
Skip Montanaro269b83b2001-02-06 01:07:02 +0000112
Guido van Rossuma28dab51997-08-29 22:36:47 +0000113del _names
114
Martin v. Löwis22b457e2005-01-16 08:40:58 +0000115# Python uses fixed values for the SEEK_ constants; they are mapped
116# to native constants if necessary in posixmodule.c
117SEEK_SET = 0
118SEEK_CUR = 1
119SEEK_END = 2
120
Terry Reedy5a22b652010-12-02 07:05:56 +0000121
122def _get_masked_mode(mode):
123 mask = umask(0)
124 umask(mask)
125 return mode & ~mask
126
Charles-François Natali7372b062012-02-05 15:15:38 +0100127def _are_same_file(stat1, stat2):
128 """Helper function that checks whether two stat results refer to the same
129 file.
130 """
131 return (stat1.st_ino == stat2.st_ino and stat1.st_dev == stat2.st_dev)
132#
Skip Montanaro269b83b2001-02-06 01:07:02 +0000133
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:
Terry Reedy5a22b652010-12-02 07:05:56 +0000163 if not (e.errno == errno.EEXIST and exist_ok and path.isdir(name) and
164 st.S_IMODE(lstat(name).st_mode) == _get_masked_mode(mode)):
165 raise
Guido van Rossum4def7de1998-07-24 20:48:03 +0000166
167def removedirs(name):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000168 """removedirs(path)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000169
Fredrik Lundh96c1c7a2005-11-12 15:55:04 +0000170 Super-rmdir; remove a leaf directory and all empty intermediate
Guido van Rossum4def7de1998-07-24 20:48:03 +0000171 ones. Works like rmdir except that, if the leaf directory is
172 successfully removed, directories corresponding to rightmost path
Tim Petersc4e09402003-04-25 07:11:48 +0000173 segments will be pruned away until either the whole path is
Guido van Rossum4def7de1998-07-24 20:48:03 +0000174 consumed or an error occurs. Errors during this latter phase are
175 ignored -- they generally mean that a directory was not empty.
176
177 """
178 rmdir(name)
179 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000180 if not tail:
181 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000182 while head and tail:
183 try:
184 rmdir(head)
185 except error:
186 break
187 head, tail = path.split(head)
188
189def renames(old, new):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000190 """renames(old, new)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000191
192 Super-rename; create directories as necessary and delete any left
193 empty. Works like rename, except creation of any intermediate
194 directories needed to make the new pathname good is attempted
195 first. After the rename, directories corresponding to rightmost
196 path segments of the old name will be pruned way until either the
197 whole path is consumed or a nonempty directory is found.
198
199 Note: this function can fail with the new directory structure made
200 if you lack permissions needed to unlink the leaf directory or
201 file.
202
203 """
204 head, tail = path.split(new)
205 if head and tail and not path.exists(head):
206 makedirs(head)
207 rename(old, new)
208 head, tail = path.split(old)
209 if head and tail:
210 try:
211 removedirs(head)
212 except error:
213 pass
214
Skip Montanaro269b83b2001-02-06 01:07:02 +0000215__all__.extend(["makedirs", "removedirs", "renames"])
216
Guido van Rossumd8faa362007-04-27 19:54:29 +0000217def walk(top, topdown=True, onerror=None, followlinks=False):
Tim Petersc4e09402003-04-25 07:11:48 +0000218 """Directory tree generator.
219
220 For each directory in the directory tree rooted at top (including top
221 itself, but excluding '.' and '..'), yields a 3-tuple
222
223 dirpath, dirnames, filenames
224
225 dirpath is a string, the path to the directory. dirnames is a list of
226 the names of the subdirectories in dirpath (excluding '.' and '..').
227 filenames is a list of the names of the non-directory files in dirpath.
228 Note that the names in the lists are just names, with no path components.
229 To get a full path (which begins with top) to a file or directory in
230 dirpath, do os.path.join(dirpath, name).
231
232 If optional arg 'topdown' is true or not specified, the triple for a
233 directory is generated before the triples for any of its subdirectories
234 (directories are generated top down). If topdown is false, the triple
235 for a directory is generated after the triples for all of its
236 subdirectories (directories are generated bottom up).
237
238 When topdown is true, the caller can modify the dirnames list in-place
239 (e.g., via del or slice assignment), and walk will only recurse into the
240 subdirectories whose names remain in dirnames; this can be used to prune
241 the search, or to impose a specific order of visiting. Modifying
242 dirnames when topdown is false is ineffective, since the directories in
243 dirnames have already been generated by the time dirnames itself is
244 generated.
245
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000246 By default errors from the os.listdir() call are ignored. If
247 optional arg 'onerror' is specified, it should be a function; it
248 will be called with one argument, an os.error instance. It can
249 report the error to continue with the walk, or raise the exception
250 to abort the walk. Note that the filename is available as the
251 filename attribute of the exception object.
252
Guido van Rossumd8faa362007-04-27 19:54:29 +0000253 By default, os.walk does not follow symbolic links to subdirectories on
254 systems that support them. In order to get this functionality, set the
255 optional argument 'followlinks' to true.
256
Tim Petersc4e09402003-04-25 07:11:48 +0000257 Caution: if you pass a relative pathname for top, don't change the
258 current working directory between resumptions of walk. walk never
259 changes the current directory, and assumes that the client doesn't
260 either.
261
262 Example:
263
Christian Heimes5d8da202008-05-06 13:58:24 +0000264 import os
Tim Petersc4e09402003-04-25 07:11:48 +0000265 from os.path import join, getsize
Christian Heimes5d8da202008-05-06 13:58:24 +0000266 for root, dirs, files in os.walk('python/Lib/email'):
Neal Norwitz752abd02008-05-13 04:55:24 +0000267 print(root, "consumes", end="")
268 print(sum([getsize(join(root, name)) for name in files]), end="")
269 print("bytes in", len(files), "non-directory files")
Tim Petersc4e09402003-04-25 07:11:48 +0000270 if 'CVS' in dirs:
271 dirs.remove('CVS') # don't visit CVS directories
272 """
273
Benjamin Petersonf6489f92009-11-25 17:46:26 +0000274 islink, join, isdir = path.islink, path.join, path.isdir
Tim Petersc4e09402003-04-25 07:11:48 +0000275
276 # We may not have read permission for top, in which case we can't
Alexandre Vassalotti4e6531e2008-05-09 20:00:17 +0000277 # get a list of the files the directory contains. os.walk
Tim Petersc4e09402003-04-25 07:11:48 +0000278 # always suppressed the exception then, rather than blow up for a
279 # minor reason when (say) a thousand readable directories are still
280 # left to visit. That logic is copied here.
281 try:
282 # Note that listdir and error are globals in this module due
283 # to earlier import-*.
284 names = listdir(top)
Guido van Rossumb940e112007-01-10 16:19:56 +0000285 except error as err:
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000286 if onerror is not None:
287 onerror(err)
Tim Petersc4e09402003-04-25 07:11:48 +0000288 return
289
290 dirs, nondirs = [], []
291 for name in names:
292 if isdir(join(top, name)):
293 dirs.append(name)
294 else:
295 nondirs.append(name)
296
297 if topdown:
298 yield top, dirs, nondirs
299 for name in dirs:
Benjamin Petersonf6489f92009-11-25 17:46:26 +0000300 new_path = join(top, name)
301 if followlinks or not islink(new_path):
302 for x in walk(new_path, topdown, onerror, followlinks):
Tim Petersc4e09402003-04-25 07:11:48 +0000303 yield x
304 if not topdown:
305 yield top, dirs, nondirs
306
307__all__.append("walk")
308
Charles-François Natali7372b062012-02-05 15:15:38 +0100309if _exists("openat"):
310
311 def fwalk(top, topdown=True, onerror=None, followlinks=False):
312 """Directory tree generator.
313
314 This behaves exactly like walk(), except that it yields a 4-tuple
315
316 dirpath, dirnames, filenames, dirfd
317
318 `dirpath`, `dirnames` and `filenames` are identical to walk() output,
319 and `dirfd` is a file descriptor referring to the directory `dirpath`.
320
321 The advantage of walkfd() over walk() is that it's safe against symlink
322 races (when followlinks is False).
323
324 Caution:
325 Since fwalk() yields file descriptors, those are only valid until the
326 next iteration step, so you should dup() them if you want to keep them
327 for a longer period.
328
329 Example:
330
331 import os
332 for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
333 print(root, "consumes", end="")
334 print(sum([os.fstatat(rootfd, name).st_size for name in files]),
335 end="")
336 print("bytes in", len(files), "non-directory files")
337 if 'CVS' in dirs:
338 dirs.remove('CVS') # don't visit CVS directories
339 """
340 # Note: To guard against symlink races, we use the standard
341 # lstat()/open()/fstat() trick.
342 orig_st = lstat(top)
343 topfd = open(top, O_RDONLY)
344 try:
345 if (followlinks or (st.S_ISDIR(orig_st.st_mode) and
346 _are_same_file(orig_st, fstat(topfd)))):
347 for x in _fwalk(topfd, top, topdown, onerror, followlinks):
348 yield x
349 finally:
350 close(topfd)
351
352 def _fwalk(topfd, toppath, topdown, onerror, followlinks):
353 # Note: This uses O(depth of the directory tree) file descriptors: if
354 # necessary, it can be adapted to only require O(1) FDs, see issue
355 # #13734.
356
357 # whether to follow symlinks
358 flag = 0 if followlinks else AT_SYMLINK_NOFOLLOW
359
Charles-François Natali77940902012-02-06 19:54:48 +0100360 names = flistdir(topfd)
Charles-François Natali7372b062012-02-05 15:15:38 +0100361 dirs, nondirs = [], []
362 for name in names:
363 # Here, we don't use AT_SYMLINK_NOFOLLOW to be consistent with
364 # walk() which reports symlinks to directories as directories. We do
365 # however check for symlinks before recursing into a subdirectory.
366 if st.S_ISDIR(fstatat(topfd, name).st_mode):
367 dirs.append(name)
368 else:
369 nondirs.append(name)
370
371 if topdown:
372 yield toppath, dirs, nondirs, topfd
373
374 for name in dirs:
375 try:
376 orig_st = fstatat(topfd, name, flag)
377 dirfd = openat(topfd, name, O_RDONLY)
378 except error as err:
379 if onerror is not None:
380 onerror(err)
381 return
382 try:
383 if followlinks or _are_same_file(orig_st, fstat(dirfd)):
384 dirpath = path.join(toppath, name)
385 for x in _fwalk(dirfd, dirpath, topdown, onerror, followlinks):
386 yield x
387 finally:
388 close(dirfd)
389
390 if not topdown:
391 yield toppath, dirs, nondirs, topfd
392
393 __all__.append("fwalk")
394
Guido van Rossuma28dab51997-08-29 22:36:47 +0000395# Make sure os.environ exists, at least
396try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000397 environ
Guido van Rossuma28dab51997-08-29 22:36:47 +0000398except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000399 environ = {}
Guido van Rossuma28dab51997-08-29 22:36:47 +0000400
Guido van Rossume65cce51993-11-08 15:05:21 +0000401def execl(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000402 """execl(file, *args)
403
404 Execute the executable file with argument list args, replacing the
405 current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000406 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000407
408def execle(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000409 """execle(file, *args, env)
410
411 Execute the executable file with argument list args and
412 environment env, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000413 env = args[-1]
414 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000415
416def execlp(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000417 """execlp(file, *args)
418
419 Execute the executable file (which is searched for along $PATH)
420 with argument list args, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000421 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000422
Guido van Rossum030afb11995-03-14 17:27:18 +0000423def execlpe(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000424 """execlpe(file, *args, env)
425
426 Execute the executable file (which is searched for along $PATH)
427 with argument list args and environment env, replacing the current
Tim Peters2344fae2001-01-15 00:50:52 +0000428 process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000429 env = args[-1]
430 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000431
Guido van Rossume65cce51993-11-08 15:05:21 +0000432def execvp(file, args):
Matthias Klosea09c54f2010-01-31 16:48:44 +0000433 """execvp(file, args)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000434
435 Execute the executable file (which is searched for along $PATH)
436 with argument list args, replacing the current process.
Thomas Wouters7e474022000-07-16 12:04:32 +0000437 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000438 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000439
440def execvpe(file, args, env):
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000441 """execvpe(file, args, env)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000442
443 Execute the executable file (which is searched for along $PATH)
444 with argument list args and environment env , replacing the
445 current process.
Tim Peters2344fae2001-01-15 00:50:52 +0000446 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000447 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000448
Skip Montanaro269b83b2001-02-06 01:07:02 +0000449__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
450
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000451def _execvpe(file, args, env=None):
452 if env is not None:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000453 exec_func = execve
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000454 argrest = (args, env)
455 else:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000456 exec_func = execv
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000457 argrest = (args,)
458 env = environ
Guido van Rossumaed51d82002-08-05 16:13:24 +0000459
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000460 head, tail = path.split(file)
461 if head:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000462 exec_func(file, *argrest)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000463 return
Guido van Rossume7ba4952007-06-06 23:52:48 +0000464 last_exc = saved_exc = None
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000465 saved_tb = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000466 path_list = get_exec_path(env)
467 if name != 'nt':
468 file = fsencode(file)
469 path_list = map(fsencode, path_list)
470 for dir in path_list:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000471 fullname = path.join(dir, file)
472 try:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000473 exec_func(fullname, *argrest)
Guido van Rossumb940e112007-01-10 16:19:56 +0000474 except error as e:
Guido van Rossume7ba4952007-06-06 23:52:48 +0000475 last_exc = e
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000476 tb = sys.exc_info()[2]
Christian Heimes45f9af32007-11-27 21:50:00 +0000477 if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000478 and saved_exc is None):
479 saved_exc = e
480 saved_tb = tb
481 if saved_exc:
Benjamin Peterson4b068192009-02-20 03:19:25 +0000482 raise saved_exc.with_traceback(saved_tb)
483 raise last_exc.with_traceback(tb)
Guido van Rossumd74fb6b2001-03-02 06:43:49 +0000484
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000485
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000486def get_exec_path(env=None):
487 """Returns the sequence of directories that will be searched for the
488 named executable (similar to a shell) when launching a process.
489
490 *env* must be an environment variable dict or None. If *env* is None,
491 os.environ will be used.
492 """
Victor Stinner273b7662010-11-06 12:59:33 +0000493 # Use a local import instead of a global import to limit the number of
494 # modules loaded at startup: the os module is always loaded at startup by
495 # Python. It may also avoid a bootstrap issue.
Victor Stinner6f35eda2010-10-29 00:38:58 +0000496 import warnings
497
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000498 if env is None:
499 env = environ
Victor Stinnerb745a742010-05-18 17:17:23 +0000500
Victor Stinnerbb4f2182010-11-07 15:43:39 +0000501 # {b'PATH': ...}.get('PATH') and {'PATH': ...}.get(b'PATH') emit a
502 # BytesWarning when using python -b or python -bb: ignore the warning
Victor Stinner273b7662010-11-06 12:59:33 +0000503 with warnings.catch_warnings():
504 warnings.simplefilter("ignore", BytesWarning)
Victor Stinnerb745a742010-05-18 17:17:23 +0000505
Victor Stinnerb745a742010-05-18 17:17:23 +0000506 try:
Victor Stinner273b7662010-11-06 12:59:33 +0000507 path_list = env.get('PATH')
508 except TypeError:
509 path_list = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000510
Victor Stinner273b7662010-11-06 12:59:33 +0000511 if supports_bytes_environ:
512 try:
513 path_listb = env[b'PATH']
514 except (KeyError, TypeError):
515 pass
516 else:
517 if path_list is not None:
518 raise ValueError(
519 "env cannot contain 'PATH' and b'PATH' keys")
520 path_list = path_listb
521
522 if path_list is not None and isinstance(path_list, bytes):
523 path_list = fsdecode(path_list)
Victor Stinnerb745a742010-05-18 17:17:23 +0000524
525 if path_list is None:
526 path_list = defpath
527 return path_list.split(pathsep)
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000528
529
Skip Montanaro289bc052007-08-17 02:30:27 +0000530# Change environ to automatically call putenv(), unsetenv if they exist.
Raymond Hettinger158c9c22011-02-22 00:41:50 +0000531from collections.abc import MutableMapping
Skip Montanaro289bc052007-08-17 02:30:27 +0000532
533class _Environ(MutableMapping):
Victor Stinner84ae1182010-05-06 22:05:07 +0000534 def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue, putenv, unsetenv):
535 self.encodekey = encodekey
536 self.decodekey = decodekey
537 self.encodevalue = encodevalue
538 self.decodevalue = decodevalue
Skip Montanaro289bc052007-08-17 02:30:27 +0000539 self.putenv = putenv
540 self.unsetenv = unsetenv
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000541 self._data = data
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000542
Skip Montanaro289bc052007-08-17 02:30:27 +0000543 def __getitem__(self, key):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000544 value = self._data[self.encodekey(key)]
Victor Stinner84ae1182010-05-06 22:05:07 +0000545 return self.decodevalue(value)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000546
Skip Montanaro289bc052007-08-17 02:30:27 +0000547 def __setitem__(self, key, value):
Victor Stinner84ae1182010-05-06 22:05:07 +0000548 key = self.encodekey(key)
549 value = self.encodevalue(value)
Skip Montanaro289bc052007-08-17 02:30:27 +0000550 self.putenv(key, value)
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000551 self._data[key] = value
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000552
Skip Montanaro289bc052007-08-17 02:30:27 +0000553 def __delitem__(self, key):
Victor Stinner84ae1182010-05-06 22:05:07 +0000554 key = self.encodekey(key)
Skip Montanaro289bc052007-08-17 02:30:27 +0000555 self.unsetenv(key)
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000556 del self._data[key]
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000557
Skip Montanaro289bc052007-08-17 02:30:27 +0000558 def __iter__(self):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000559 for key in self._data:
Victor Stinner84ae1182010-05-06 22:05:07 +0000560 yield self.decodekey(key)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000561
Skip Montanaro289bc052007-08-17 02:30:27 +0000562 def __len__(self):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000563 return len(self._data)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000564
565 def __repr__(self):
Victor Stinnerbed71172010-07-28 21:25:42 +0000566 return 'environ({{{}}})'.format(', '.join(
Victor Stinnerd73c1a32010-07-28 21:23:23 +0000567 ('{!r}: {!r}'.format(self.decodekey(key), self.decodevalue(value))
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000568 for key, value in self._data.items())))
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000569
Skip Montanaro289bc052007-08-17 02:30:27 +0000570 def copy(self):
571 return dict(self)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000572
Skip Montanaro289bc052007-08-17 02:30:27 +0000573 def setdefault(self, key, value):
574 if key not in self:
575 self[key] = value
576 return self[key]
577
578try:
579 _putenv = putenv
580except NameError:
581 _putenv = lambda key, value: None
Martin v. Löwisa90f4382001-03-07 09:05:45 +0000582else:
Skip Montanaro289bc052007-08-17 02:30:27 +0000583 __all__.append("putenv")
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000584
Skip Montanaro289bc052007-08-17 02:30:27 +0000585try:
586 _unsetenv = unsetenv
587except NameError:
588 _unsetenv = lambda key: _putenv(key, "")
589else:
590 __all__.append("unsetenv")
Guido van Rossumc524d952001-10-19 01:31:59 +0000591
Victor Stinner84ae1182010-05-06 22:05:07 +0000592def _createenviron():
593 if name in ('os2', 'nt'):
594 # Where Env Var Names Must Be UPPERCASE
595 def check_str(value):
596 if not isinstance(value, str):
597 raise TypeError("str expected, not %s" % type(value).__name__)
598 return value
599 encode = check_str
600 decode = str
601 def encodekey(key):
602 return encode(key).upper()
603 data = {}
604 for key, value in environ.items():
605 data[encodekey(key)] = value
606 else:
607 # Where Env Var Names Can Be Mixed Case
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000608 encoding = sys.getfilesystemencoding()
Victor Stinner84ae1182010-05-06 22:05:07 +0000609 def encode(value):
610 if not isinstance(value, str):
611 raise TypeError("str expected, not %s" % type(value).__name__)
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000612 return value.encode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000613 def decode(value):
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000614 return value.decode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000615 encodekey = encode
616 data = environ
617 return _Environ(data,
618 encodekey, decode,
619 encode, decode,
620 _putenv, _unsetenv)
Guido van Rossumc524d952001-10-19 01:31:59 +0000621
Victor Stinner84ae1182010-05-06 22:05:07 +0000622# unicode environ
623environ = _createenviron()
624del _createenviron
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000625
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000626
Jack Jansenb11ce9b2003-01-08 16:33:40 +0000627def getenv(key, default=None):
Tim Peters2c60f7a2003-01-29 03:49:43 +0000628 """Get an environment variable, return None if it doesn't exist.
Victor Stinner84ae1182010-05-06 22:05:07 +0000629 The optional second argument can specify an alternate default.
630 key, default and the result are str."""
Tim Peters2c60f7a2003-01-29 03:49:43 +0000631 return environ.get(key, default)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000632
Victor Stinnerb745a742010-05-18 17:17:23 +0000633supports_bytes_environ = name not in ('os2', 'nt')
634__all__.extend(("getenv", "supports_bytes_environ"))
635
636if supports_bytes_environ:
Victor Stinner84ae1182010-05-06 22:05:07 +0000637 def _check_bytes(value):
638 if not isinstance(value, bytes):
639 raise TypeError("bytes expected, not %s" % type(value).__name__)
640 return value
641
642 # bytes environ
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000643 environb = _Environ(environ._data,
Victor Stinner84ae1182010-05-06 22:05:07 +0000644 _check_bytes, bytes,
645 _check_bytes, bytes,
646 _putenv, _unsetenv)
647 del _check_bytes
648
649 def getenvb(key, default=None):
650 """Get an environment variable, return None if it doesn't exist.
651 The optional second argument can specify an alternate default.
652 key, default and the result are bytes."""
653 return environb.get(key, default)
Victor Stinner70120e22010-07-29 17:19:38 +0000654
655 __all__.extend(("environb", "getenvb"))
Victor Stinner84ae1182010-05-06 22:05:07 +0000656
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000657def _fscodec():
658 encoding = sys.getfilesystemencoding()
659 if encoding == 'mbcs':
Victor Stinnere882aac2010-10-24 21:12:26 +0000660 errors = 'strict'
Victor Stinner313a1202010-06-11 23:56:51 +0000661 else:
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000662 errors = 'surrogateescape'
Victor Stinnere8d51452010-08-19 01:05:19 +0000663
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000664 def fsencode(filename):
665 """
666 Encode filename to the filesystem encoding with 'surrogateescape' error
667 handler, return bytes unchanged. On Windows, use 'strict' error handler if
668 the file system encoding is 'mbcs' (which is the default encoding).
669 """
670 if isinstance(filename, bytes):
671 return filename
672 elif isinstance(filename, str):
673 return filename.encode(encoding, errors)
Victor Stinnere8d51452010-08-19 01:05:19 +0000674 else:
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000675 raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
676
677 def fsdecode(filename):
678 """
679 Decode filename from the filesystem encoding with 'surrogateescape' error
680 handler, return str unchanged. On Windows, use 'strict' error handler if
681 the file system encoding is 'mbcs' (which is the default encoding).
682 """
683 if isinstance(filename, str):
684 return filename
685 elif isinstance(filename, bytes):
686 return filename.decode(encoding, errors)
687 else:
688 raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
689
690 return fsencode, fsdecode
691
692fsencode, fsdecode = _fscodec()
693del _fscodec
Victor Stinner449c4662010-05-08 11:10:09 +0000694
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000695# Supply spawn*() (probably only for Unix)
696if _exists("fork") and not _exists("spawnv") and _exists("execv"):
697
698 P_WAIT = 0
699 P_NOWAIT = P_NOWAITO = 1
700
701 # XXX Should we support P_DETACH? I suppose it could fork()**2
702 # and close the std I/O streams. Also, P_OVERLAY is the same
703 # as execv*()?
704
705 def _spawnvef(mode, file, args, env, func):
706 # Internal helper; func is the exec*() function to use
707 pid = fork()
708 if not pid:
709 # Child
710 try:
711 if env is None:
712 func(file, args)
713 else:
714 func(file, args, env)
715 except:
716 _exit(127)
717 else:
718 # Parent
719 if mode == P_NOWAIT:
720 return pid # Caller is responsible for waiting!
721 while 1:
722 wpid, sts = waitpid(pid, 0)
723 if WIFSTOPPED(sts):
724 continue
725 elif WIFSIGNALED(sts):
726 return -WTERMSIG(sts)
727 elif WIFEXITED(sts):
728 return WEXITSTATUS(sts)
729 else:
Collin Winter828f04a2007-08-31 00:04:24 +0000730 raise error("Not stopped, signaled or exited???")
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000731
732 def spawnv(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000733 """spawnv(mode, file, args) -> integer
734
735Execute file with arguments from args in a subprocess.
736If mode == P_NOWAIT return the pid of the process.
737If mode == P_WAIT return the process's exit code if it exits normally;
Tim Peters2344fae2001-01-15 00:50:52 +0000738otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000739 return _spawnvef(mode, file, args, None, execv)
740
741 def spawnve(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000742 """spawnve(mode, file, args, env) -> integer
743
744Execute file with arguments from args in a subprocess with the
745specified environment.
746If mode == P_NOWAIT return the pid of the process.
747If mode == P_WAIT return the process's exit code if it exits normally;
748otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000749 return _spawnvef(mode, file, args, env, execve)
750
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000751 # Note: spawnvp[e] is't currently supported on Windows
752
753 def spawnvp(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000754 """spawnvp(mode, file, args) -> integer
755
756Execute file (which is looked for along $PATH) with arguments from
757args 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;
760otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000761 return _spawnvef(mode, file, args, None, execvp)
762
763 def spawnvpe(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000764 """spawnvpe(mode, file, args, env) -> integer
765
766Execute file (which is looked for along $PATH) with arguments from
767args in a subprocess with the supplied 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 Rossumdd7cbbf1999-11-02 20:44:07 +0000771 return _spawnvef(mode, file, args, env, execvpe)
772
773if _exists("spawnv"):
774 # These aren't supplied by the basic Windows code
775 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000776
777 def spawnl(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000778 """spawnl(mode, file, *args) -> integer
779
780Execute file with arguments from args in a subprocess.
781If mode == P_NOWAIT return the pid of the process.
782If mode == P_WAIT return the process's exit code if it exits normally;
783otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000784 return spawnv(mode, file, args)
785
786 def spawnle(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000787 """spawnle(mode, file, *args, env) -> integer
788
789Execute file with arguments from args in a subprocess with the
790supplied environment.
791If mode == P_NOWAIT return the pid of the process.
792If mode == P_WAIT return the process's exit code if it exits normally;
793otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000794 env = args[-1]
795 return spawnve(mode, file, args[:-1], env)
796
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000797
798 __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
799
800
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000801if _exists("spawnvp"):
802 # At the moment, Windows doesn't implement spawnvp[e],
803 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000804 def spawnlp(mode, file, *args):
Neal Norwitzb7f68102003-07-02 02:49:33 +0000805 """spawnlp(mode, file, *args) -> integer
Guido van Rossume0cd2912000-04-21 18:35:36 +0000806
807Execute file (which is looked for along $PATH) with arguments from
808args in a subprocess with the supplied environment.
809If mode == P_NOWAIT return the pid of the process.
810If mode == P_WAIT return the process's exit code if it exits normally;
811otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000812 return spawnvp(mode, file, args)
813
814 def spawnlpe(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000815 """spawnlpe(mode, file, *args, env) -> integer
816
817Execute file (which is looked for along $PATH) with arguments from
818args in a subprocess with the supplied environment.
819If mode == P_NOWAIT return the pid of the process.
820If mode == P_WAIT return the process's exit code if it exits normally;
821otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000822 env = args[-1]
823 return spawnvpe(mode, file, args[:-1], env)
Guido van Rossume0cd2912000-04-21 18:35:36 +0000824
825
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000826 __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
Skip Montanaro269b83b2001-02-06 01:07:02 +0000827
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000828import copyreg as _copyreg
Michael W. Hudson0e025302002-03-06 17:11:18 +0000829
830def _make_stat_result(tup, dict):
831 return stat_result(tup, dict)
832
833def _pickle_stat_result(sr):
834 (type, args) = sr.__reduce__()
835 return (_make_stat_result, args)
836
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000837try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000838 _copyreg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000839except NameError: # stat_result may not exist
840 pass
Michael W. Hudson0e025302002-03-06 17:11:18 +0000841
842def _make_statvfs_result(tup, dict):
843 return statvfs_result(tup, dict)
844
845def _pickle_statvfs_result(sr):
846 (type, args) = sr.__reduce__()
847 return (_make_statvfs_result, args)
848
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000849try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000850 _copyreg.pickle(statvfs_result, _pickle_statvfs_result,
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000851 _make_statvfs_result)
Michael W. Hudsone5363b72002-03-15 10:21:59 +0000852except NameError: # statvfs_result may not exist
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000853 pass
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000854
855if not _exists("urandom"):
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000856 def urandom(n):
857 """urandom(n) -> str
Tim Peters45e77c52004-08-29 18:47:31 +0000858
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000859 Return a string of n random bytes suitable for cryptographic use.
860
Tim Peters45e77c52004-08-29 18:47:31 +0000861 """
Georg Brandl9e43acf2005-07-04 17:16:07 +0000862 try:
863 _urandomfd = open("/dev/urandom", O_RDONLY)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000864 except (OSError, IOError):
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000865 raise NotImplementedError("/dev/urandom (or equivalent) not found")
Guido van Rossum572dbf82007-04-27 23:53:51 +0000866 bs = b""
867 while len(bs) < n:
868 bs += read(_urandomfd, n - len(bs))
Georg Brandl9e43acf2005-07-04 17:16:07 +0000869 close(_urandomfd)
Guido van Rossum572dbf82007-04-27 23:53:51 +0000870 return bs
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000871
872# Supply os.popen()
Antoine Pitrou877766d2011-03-19 17:00:37 +0100873def popen(cmd, mode="r", buffering=-1):
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000874 if not isinstance(cmd, str):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000875 raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
876 if mode not in ("r", "w"):
877 raise ValueError("invalid mode %r" % mode)
Antoine Pitrou877766d2011-03-19 17:00:37 +0100878 if buffering == 0 or buffering == None:
879 raise ValueError("popen() does not support unbuffered streams")
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000880 import subprocess, io
881 if mode == "r":
882 proc = subprocess.Popen(cmd,
883 shell=True,
884 stdout=subprocess.PIPE,
885 bufsize=buffering)
886 return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
887 else:
888 proc = subprocess.Popen(cmd,
889 shell=True,
890 stdin=subprocess.PIPE,
891 bufsize=buffering)
892 return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
893
894# Helper for popen() -- a proxy for a file whose close waits for the process
895class _wrap_close:
896 def __init__(self, stream, proc):
897 self._stream = stream
898 self._proc = proc
899 def close(self):
900 self._stream.close()
Amaury Forgeot d'Arc97e5f282009-07-11 09:35:13 +0000901 returncode = self._proc.wait()
902 if returncode == 0:
903 return None
904 if name == 'nt':
905 return returncode
906 else:
907 return returncode << 8 # Shift left to match old behavior
Antoine Pitrouac625352009-12-09 00:01:27 +0000908 def __enter__(self):
909 return self
910 def __exit__(self, *args):
911 self.close()
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000912 def __getattr__(self, name):
913 return getattr(self._stream, name)
Thomas Heller476157b2007-09-04 11:27:47 +0000914 def __iter__(self):
915 return iter(self._stream)
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000916
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +0000917# Supply os.fdopen()
918def fdopen(fd, *args, **kwargs):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000919 if not isinstance(fd, int):
920 raise TypeError("invalid fd type (%s, expected integer)" % type(fd))
921 import io
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +0000922 return io.open(fd, *args, **kwargs)