blob: ed2a31e88134d2a270c272cbac7dc40e627c4ba9 [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
Brett Cannonfd074152012-04-14 14:10:13 -040045# Any new dependencies of the os module and/or changes in path separator
46# requires updating importlib as well.
Guido van Rossuma28dab51997-08-29 22:36:47 +000047if 'posix' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000048 name = 'posix'
Guido van Rossume9387ea1998-05-22 15:26:04 +000049 linesep = '\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000050 from posix import *
51 try:
52 from posix import _exit
53 except ImportError:
54 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000055 import posixpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000056
Skip Montanaro269b83b2001-02-06 01:07:02 +000057 import posix
58 __all__.extend(_get_exports_list(posix))
59 del posix
60
Guido van Rossuma28dab51997-08-29 22:36:47 +000061elif 'nt' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000062 name = 'nt'
Guido van Rossume9387ea1998-05-22 15:26:04 +000063 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000064 from nt import *
Tim Peters6757c1e2003-01-08 21:20:57 +000065 try:
66 from nt import _exit
67 except ImportError:
68 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000069 import ntpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000070
Skip Montanaro269b83b2001-02-06 01:07:02 +000071 import nt
72 __all__.extend(_get_exports_list(nt))
73 del nt
74
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000075elif 'os2' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000076 name = 'os2'
Guido van Rossume9387ea1998-05-22 15:26:04 +000077 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000078 from os2 import *
79 try:
80 from os2 import _exit
81 except ImportError:
82 pass
Andrew MacIntyre5cef5712002-02-24 05:32:32 +000083 if sys.version.find('EMX GCC') == -1:
Skip Montanaro117910d2003-02-14 19:35:31 +000084 import ntpath as path
Andrew MacIntyre5cef5712002-02-24 05:32:32 +000085 else:
Skip Montanaro117910d2003-02-14 19:35:31 +000086 import os2emxpath as path
Andrew MacIntyre89f98652003-12-02 12:33:01 +000087 from _emx_link import link
Tim Petersf2715e02003-02-19 02:35:07 +000088
Skip Montanaro269b83b2001-02-06 01:07:02 +000089 import os2
90 __all__.extend(_get_exports_list(os2))
91 del os2
92
Guido van Rossum18df5d41999-06-11 01:37:27 +000093elif 'ce' in _names:
94 name = 'ce'
95 linesep = '\r\n'
Guido van Rossum18df5d41999-06-11 01:37:27 +000096 from ce import *
Tim Peters6757c1e2003-01-08 21:20:57 +000097 try:
98 from ce import _exit
99 except ImportError:
100 pass
Guido van Rossum18df5d41999-06-11 01:37:27 +0000101 # We can use the standard Windows path.
Skip Montanaro117910d2003-02-14 19:35:31 +0000102 import ntpath as path
Tim Petersf2715e02003-02-19 02:35:07 +0000103
Skip Montanaro269b83b2001-02-06 01:07:02 +0000104 import ce
105 __all__.extend(_get_exports_list(ce))
106 del ce
107
Guido van Rossum2979b011994-08-01 11:18:30 +0000108else:
Collin Winter828f04a2007-08-31 00:04:24 +0000109 raise ImportError('no os specific module found')
Guido van Rossume65cce51993-11-08 15:05:21 +0000110
Skip Montanaro117910d2003-02-14 19:35:31 +0000111sys.modules['os.path'] = path
Georg Brandled5b9b32008-12-05 07:45:54 +0000112from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
113 devnull)
Skip Montanaro269b83b2001-02-06 01:07:02 +0000114
Guido van Rossuma28dab51997-08-29 22:36:47 +0000115del _names
116
Martin v. Löwis22b457e2005-01-16 08:40:58 +0000117# Python uses fixed values for the SEEK_ constants; they are mapped
118# to native constants if necessary in posixmodule.c
119SEEK_SET = 0
120SEEK_CUR = 1
121SEEK_END = 2
122
Terry Reedy5a22b652010-12-02 07:05:56 +0000123
124def _get_masked_mode(mode):
125 mask = umask(0)
126 umask(mask)
127 return mode & ~mask
128
Guido van Rossum4def7de1998-07-24 20:48:03 +0000129# Super directory utilities.
130# (Inspired by Eric Raymond; the doc strings are mostly his)
131
Terry Reedy5a22b652010-12-02 07:05:56 +0000132def makedirs(name, mode=0o777, exist_ok=False):
133 """makedirs(path [, mode=0o777][, exist_ok=False])
Guido van Rossum4def7de1998-07-24 20:48:03 +0000134
135 Super-mkdir; create a leaf directory and all intermediate ones.
136 Works like mkdir, except that any intermediate path segment (not
Terry Reedy5a22b652010-12-02 07:05:56 +0000137 just the rightmost) will be created if it does not exist. If the
138 target directory with the same mode as we specified already exists,
139 raises an OSError if exist_ok is False, otherwise no exception is
140 raised. This is recursive.
Guido van Rossum4def7de1998-07-24 20:48:03 +0000141
142 """
143 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000144 if not tail:
145 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000146 if head and tail and not path.exists(head):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000147 try:
Terry Reedy5a22b652010-12-02 07:05:56 +0000148 makedirs(head, mode, exist_ok)
Guido van Rossumb940e112007-01-10 16:19:56 +0000149 except OSError as e:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000150 # be happy if someone already created the path
Christian Heimes45f9af32007-11-27 21:50:00 +0000151 if e.errno != errno.EEXIST:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000152 raise
Andrew M. Kuchling6fccc8a2003-12-23 16:33:28 +0000153 if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists
154 return
Terry Reedy5a22b652010-12-02 07:05:56 +0000155 try:
156 mkdir(name, mode)
157 except OSError as e:
Terry Reedy5a22b652010-12-02 07:05:56 +0000158 if not (e.errno == errno.EEXIST and exist_ok and path.isdir(name) and
159 st.S_IMODE(lstat(name).st_mode) == _get_masked_mode(mode)):
160 raise
Guido van Rossum4def7de1998-07-24 20:48:03 +0000161
162def removedirs(name):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000163 """removedirs(path)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000164
Fredrik Lundh96c1c7a2005-11-12 15:55:04 +0000165 Super-rmdir; remove a leaf directory and all empty intermediate
Guido van Rossum4def7de1998-07-24 20:48:03 +0000166 ones. Works like rmdir except that, if the leaf directory is
167 successfully removed, directories corresponding to rightmost path
Tim Petersc4e09402003-04-25 07:11:48 +0000168 segments will be pruned away until either the whole path is
Guido van Rossum4def7de1998-07-24 20:48:03 +0000169 consumed or an error occurs. Errors during this latter phase are
170 ignored -- they generally mean that a directory was not empty.
171
172 """
173 rmdir(name)
174 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000175 if not tail:
176 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000177 while head and tail:
178 try:
179 rmdir(head)
180 except error:
181 break
182 head, tail = path.split(head)
183
184def renames(old, new):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000185 """renames(old, new)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000186
187 Super-rename; create directories as necessary and delete any left
188 empty. Works like rename, except creation of any intermediate
189 directories needed to make the new pathname good is attempted
190 first. After the rename, directories corresponding to rightmost
191 path segments of the old name will be pruned way until either the
192 whole path is consumed or a nonempty directory is found.
193
194 Note: this function can fail with the new directory structure made
195 if you lack permissions needed to unlink the leaf directory or
196 file.
197
198 """
199 head, tail = path.split(new)
200 if head and tail and not path.exists(head):
201 makedirs(head)
202 rename(old, new)
203 head, tail = path.split(old)
204 if head and tail:
205 try:
206 removedirs(head)
207 except error:
208 pass
209
Skip Montanaro269b83b2001-02-06 01:07:02 +0000210__all__.extend(["makedirs", "removedirs", "renames"])
211
Guido van Rossumd8faa362007-04-27 19:54:29 +0000212def walk(top, topdown=True, onerror=None, followlinks=False):
Tim Petersc4e09402003-04-25 07:11:48 +0000213 """Directory tree generator.
214
215 For each directory in the directory tree rooted at top (including top
216 itself, but excluding '.' and '..'), yields a 3-tuple
217
218 dirpath, dirnames, filenames
219
220 dirpath is a string, the path to the directory. dirnames is a list of
221 the names of the subdirectories in dirpath (excluding '.' and '..').
222 filenames is a list of the names of the non-directory files in dirpath.
223 Note that the names in the lists are just names, with no path components.
224 To get a full path (which begins with top) to a file or directory in
225 dirpath, do os.path.join(dirpath, name).
226
227 If optional arg 'topdown' is true or not specified, the triple for a
228 directory is generated before the triples for any of its subdirectories
229 (directories are generated top down). If topdown is false, the triple
230 for a directory is generated after the triples for all of its
231 subdirectories (directories are generated bottom up).
232
233 When topdown is true, the caller can modify the dirnames list in-place
234 (e.g., via del or slice assignment), and walk will only recurse into the
235 subdirectories whose names remain in dirnames; this can be used to prune
236 the search, or to impose a specific order of visiting. Modifying
237 dirnames when topdown is false is ineffective, since the directories in
238 dirnames have already been generated by the time dirnames itself is
239 generated.
240
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000241 By default errors from the os.listdir() call are ignored. If
242 optional arg 'onerror' is specified, it should be a function; it
243 will be called with one argument, an os.error instance. It can
244 report the error to continue with the walk, or raise the exception
245 to abort the walk. Note that the filename is available as the
246 filename attribute of the exception object.
247
Guido van Rossumd8faa362007-04-27 19:54:29 +0000248 By default, os.walk does not follow symbolic links to subdirectories on
249 systems that support them. In order to get this functionality, set the
250 optional argument 'followlinks' to true.
251
Tim Petersc4e09402003-04-25 07:11:48 +0000252 Caution: if you pass a relative pathname for top, don't change the
253 current working directory between resumptions of walk. walk never
254 changes the current directory, and assumes that the client doesn't
255 either.
256
257 Example:
258
Christian Heimes5d8da202008-05-06 13:58:24 +0000259 import os
Tim Petersc4e09402003-04-25 07:11:48 +0000260 from os.path import join, getsize
Christian Heimes5d8da202008-05-06 13:58:24 +0000261 for root, dirs, files in os.walk('python/Lib/email'):
Neal Norwitz752abd02008-05-13 04:55:24 +0000262 print(root, "consumes", end="")
263 print(sum([getsize(join(root, name)) for name in files]), end="")
264 print("bytes in", len(files), "non-directory files")
Tim Petersc4e09402003-04-25 07:11:48 +0000265 if 'CVS' in dirs:
266 dirs.remove('CVS') # don't visit CVS directories
267 """
268
Benjamin Petersonf6489f92009-11-25 17:46:26 +0000269 islink, join, isdir = path.islink, path.join, path.isdir
Tim Petersc4e09402003-04-25 07:11:48 +0000270
271 # We may not have read permission for top, in which case we can't
Alexandre Vassalotti4e6531e2008-05-09 20:00:17 +0000272 # get a list of the files the directory contains. os.walk
Tim Petersc4e09402003-04-25 07:11:48 +0000273 # always suppressed the exception then, rather than blow up for a
274 # minor reason when (say) a thousand readable directories are still
275 # left to visit. That logic is copied here.
276 try:
277 # Note that listdir and error are globals in this module due
278 # to earlier import-*.
279 names = listdir(top)
Guido van Rossumb940e112007-01-10 16:19:56 +0000280 except error as err:
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000281 if onerror is not None:
282 onerror(err)
Tim Petersc4e09402003-04-25 07:11:48 +0000283 return
284
285 dirs, nondirs = [], []
286 for name in names:
287 if isdir(join(top, name)):
288 dirs.append(name)
289 else:
290 nondirs.append(name)
291
292 if topdown:
293 yield top, dirs, nondirs
294 for name in dirs:
Benjamin Petersonf6489f92009-11-25 17:46:26 +0000295 new_path = join(top, name)
296 if followlinks or not islink(new_path):
Benjamin Peterson569d0872012-05-10 16:17:35 -0500297 yield from walk(new_path, topdown, onerror, followlinks)
Tim Petersc4e09402003-04-25 07:11:48 +0000298 if not topdown:
299 yield top, dirs, nondirs
300
301__all__.append("walk")
302
Charles-François Natali7372b062012-02-05 15:15:38 +0100303if _exists("openat"):
304
305 def fwalk(top, topdown=True, onerror=None, followlinks=False):
306 """Directory tree generator.
307
308 This behaves exactly like walk(), except that it yields a 4-tuple
309
310 dirpath, dirnames, filenames, dirfd
311
312 `dirpath`, `dirnames` and `filenames` are identical to walk() output,
313 and `dirfd` is a file descriptor referring to the directory `dirpath`.
314
315 The advantage of walkfd() over walk() is that it's safe against symlink
316 races (when followlinks is False).
317
318 Caution:
319 Since fwalk() yields file descriptors, those are only valid until the
320 next iteration step, so you should dup() them if you want to keep them
321 for a longer period.
322
323 Example:
324
325 import os
326 for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
327 print(root, "consumes", end="")
328 print(sum([os.fstatat(rootfd, name).st_size for name in files]),
329 end="")
330 print("bytes in", len(files), "non-directory files")
331 if 'CVS' in dirs:
332 dirs.remove('CVS') # don't visit CVS directories
333 """
334 # Note: To guard against symlink races, we use the standard
335 # lstat()/open()/fstat() trick.
336 orig_st = lstat(top)
337 topfd = open(top, O_RDONLY)
338 try:
339 if (followlinks or (st.S_ISDIR(orig_st.st_mode) and
Charles-François Natali84c0ca02012-04-22 15:55:43 +0200340 path.samestat(orig_st, fstat(topfd)))):
Benjamin Peterson569d0872012-05-10 16:17:35 -0500341 yield from _fwalk(topfd, top, topdown, onerror, followlinks)
Charles-François Natali7372b062012-02-05 15:15:38 +0100342 finally:
343 close(topfd)
344
345 def _fwalk(topfd, toppath, topdown, onerror, followlinks):
346 # Note: This uses O(depth of the directory tree) file descriptors: if
347 # necessary, it can be adapted to only require O(1) FDs, see issue
348 # #13734.
349
350 # whether to follow symlinks
351 flag = 0 if followlinks else AT_SYMLINK_NOFOLLOW
352
Charles-François Natali77940902012-02-06 19:54:48 +0100353 names = flistdir(topfd)
Charles-François Natali7372b062012-02-05 15:15:38 +0100354 dirs, nondirs = [], []
355 for name in names:
356 # Here, we don't use AT_SYMLINK_NOFOLLOW to be consistent with
357 # walk() which reports symlinks to directories as directories. We do
358 # however check for symlinks before recursing into a subdirectory.
359 if st.S_ISDIR(fstatat(topfd, name).st_mode):
360 dirs.append(name)
361 else:
362 nondirs.append(name)
363
364 if topdown:
365 yield toppath, dirs, nondirs, topfd
366
367 for name in dirs:
368 try:
369 orig_st = fstatat(topfd, name, flag)
370 dirfd = openat(topfd, name, O_RDONLY)
371 except error as err:
372 if onerror is not None:
373 onerror(err)
374 return
375 try:
Charles-François Natali84c0ca02012-04-22 15:55:43 +0200376 if followlinks or path.samestat(orig_st, fstat(dirfd)):
Charles-François Natali7372b062012-02-05 15:15:38 +0100377 dirpath = path.join(toppath, name)
Benjamin Peterson569d0872012-05-10 16:17:35 -0500378 yield from _fwalk(dirfd, dirpath, topdown, onerror, followlinks)
Charles-François Natali7372b062012-02-05 15:15:38 +0100379 finally:
380 close(dirfd)
381
382 if not topdown:
383 yield toppath, dirs, nondirs, topfd
384
385 __all__.append("fwalk")
386
Guido van Rossuma28dab51997-08-29 22:36:47 +0000387# Make sure os.environ exists, at least
388try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000389 environ
Guido van Rossuma28dab51997-08-29 22:36:47 +0000390except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000391 environ = {}
Guido van Rossuma28dab51997-08-29 22:36:47 +0000392
Guido van Rossume65cce51993-11-08 15:05:21 +0000393def execl(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000394 """execl(file, *args)
395
396 Execute the executable file with argument list args, replacing the
397 current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000398 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000399
400def execle(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000401 """execle(file, *args, env)
402
403 Execute the executable file with argument list args and
404 environment env, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000405 env = args[-1]
406 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000407
408def execlp(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000409 """execlp(file, *args)
410
411 Execute the executable file (which is searched for along $PATH)
412 with argument list args, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000413 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000414
Guido van Rossum030afb11995-03-14 17:27:18 +0000415def execlpe(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000416 """execlpe(file, *args, env)
417
418 Execute the executable file (which is searched for along $PATH)
419 with argument list args and environment env, replacing the current
Tim Peters2344fae2001-01-15 00:50:52 +0000420 process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000421 env = args[-1]
422 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000423
Guido van Rossume65cce51993-11-08 15:05:21 +0000424def execvp(file, args):
Matthias Klosea09c54f2010-01-31 16:48:44 +0000425 """execvp(file, args)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000426
427 Execute the executable file (which is searched for along $PATH)
428 with argument list args, replacing the current process.
Thomas Wouters7e474022000-07-16 12:04:32 +0000429 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000430 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000431
432def execvpe(file, args, env):
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000433 """execvpe(file, args, env)
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 and environment env , replacing the
437 current process.
Tim Peters2344fae2001-01-15 00:50:52 +0000438 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000439 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000440
Skip Montanaro269b83b2001-02-06 01:07:02 +0000441__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
442
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000443def _execvpe(file, args, env=None):
444 if env is not None:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000445 exec_func = execve
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000446 argrest = (args, env)
447 else:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000448 exec_func = execv
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000449 argrest = (args,)
450 env = environ
Guido van Rossumaed51d82002-08-05 16:13:24 +0000451
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000452 head, tail = path.split(file)
453 if head:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000454 exec_func(file, *argrest)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000455 return
Guido van Rossume7ba4952007-06-06 23:52:48 +0000456 last_exc = saved_exc = None
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000457 saved_tb = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000458 path_list = get_exec_path(env)
459 if name != 'nt':
460 file = fsencode(file)
461 path_list = map(fsencode, path_list)
462 for dir in path_list:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000463 fullname = path.join(dir, file)
464 try:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000465 exec_func(fullname, *argrest)
Guido van Rossumb940e112007-01-10 16:19:56 +0000466 except error as e:
Guido van Rossume7ba4952007-06-06 23:52:48 +0000467 last_exc = e
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000468 tb = sys.exc_info()[2]
Christian Heimes45f9af32007-11-27 21:50:00 +0000469 if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000470 and saved_exc is None):
471 saved_exc = e
472 saved_tb = tb
473 if saved_exc:
Benjamin Peterson4b068192009-02-20 03:19:25 +0000474 raise saved_exc.with_traceback(saved_tb)
475 raise last_exc.with_traceback(tb)
Guido van Rossumd74fb6b2001-03-02 06:43:49 +0000476
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000477
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000478def get_exec_path(env=None):
479 """Returns the sequence of directories that will be searched for the
480 named executable (similar to a shell) when launching a process.
481
482 *env* must be an environment variable dict or None. If *env* is None,
483 os.environ will be used.
484 """
Victor Stinner273b7662010-11-06 12:59:33 +0000485 # Use a local import instead of a global import to limit the number of
486 # modules loaded at startup: the os module is always loaded at startup by
487 # Python. It may also avoid a bootstrap issue.
Victor Stinner6f35eda2010-10-29 00:38:58 +0000488 import warnings
489
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000490 if env is None:
491 env = environ
Victor Stinnerb745a742010-05-18 17:17:23 +0000492
Victor Stinnerbb4f2182010-11-07 15:43:39 +0000493 # {b'PATH': ...}.get('PATH') and {'PATH': ...}.get(b'PATH') emit a
494 # BytesWarning when using python -b or python -bb: ignore the warning
Victor Stinner273b7662010-11-06 12:59:33 +0000495 with warnings.catch_warnings():
496 warnings.simplefilter("ignore", BytesWarning)
Victor Stinnerb745a742010-05-18 17:17:23 +0000497
Victor Stinnerb745a742010-05-18 17:17:23 +0000498 try:
Victor Stinner273b7662010-11-06 12:59:33 +0000499 path_list = env.get('PATH')
500 except TypeError:
501 path_list = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000502
Victor Stinner273b7662010-11-06 12:59:33 +0000503 if supports_bytes_environ:
504 try:
505 path_listb = env[b'PATH']
506 except (KeyError, TypeError):
507 pass
508 else:
509 if path_list is not None:
510 raise ValueError(
511 "env cannot contain 'PATH' and b'PATH' keys")
512 path_list = path_listb
513
514 if path_list is not None and isinstance(path_list, bytes):
515 path_list = fsdecode(path_list)
Victor Stinnerb745a742010-05-18 17:17:23 +0000516
517 if path_list is None:
518 path_list = defpath
519 return path_list.split(pathsep)
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000520
521
Skip Montanaro289bc052007-08-17 02:30:27 +0000522# Change environ to automatically call putenv(), unsetenv if they exist.
Raymond Hettinger158c9c22011-02-22 00:41:50 +0000523from collections.abc import MutableMapping
Skip Montanaro289bc052007-08-17 02:30:27 +0000524
525class _Environ(MutableMapping):
Victor Stinner84ae1182010-05-06 22:05:07 +0000526 def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue, putenv, unsetenv):
527 self.encodekey = encodekey
528 self.decodekey = decodekey
529 self.encodevalue = encodevalue
530 self.decodevalue = decodevalue
Skip Montanaro289bc052007-08-17 02:30:27 +0000531 self.putenv = putenv
532 self.unsetenv = unsetenv
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000533 self._data = data
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000534
Skip Montanaro289bc052007-08-17 02:30:27 +0000535 def __getitem__(self, key):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000536 value = self._data[self.encodekey(key)]
Victor Stinner84ae1182010-05-06 22:05:07 +0000537 return self.decodevalue(value)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000538
Skip Montanaro289bc052007-08-17 02:30:27 +0000539 def __setitem__(self, key, value):
Victor Stinner84ae1182010-05-06 22:05:07 +0000540 key = self.encodekey(key)
541 value = self.encodevalue(value)
Skip Montanaro289bc052007-08-17 02:30:27 +0000542 self.putenv(key, value)
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000543 self._data[key] = value
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000544
Skip Montanaro289bc052007-08-17 02:30:27 +0000545 def __delitem__(self, key):
Victor Stinner84ae1182010-05-06 22:05:07 +0000546 key = self.encodekey(key)
Skip Montanaro289bc052007-08-17 02:30:27 +0000547 self.unsetenv(key)
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000548 del self._data[key]
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000549
Skip Montanaro289bc052007-08-17 02:30:27 +0000550 def __iter__(self):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000551 for key in self._data:
Victor Stinner84ae1182010-05-06 22:05:07 +0000552 yield self.decodekey(key)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000553
Skip Montanaro289bc052007-08-17 02:30:27 +0000554 def __len__(self):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000555 return len(self._data)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000556
557 def __repr__(self):
Victor Stinnerbed71172010-07-28 21:25:42 +0000558 return 'environ({{{}}})'.format(', '.join(
Victor Stinnerd73c1a32010-07-28 21:23:23 +0000559 ('{!r}: {!r}'.format(self.decodekey(key), self.decodevalue(value))
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000560 for key, value in self._data.items())))
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000561
Skip Montanaro289bc052007-08-17 02:30:27 +0000562 def copy(self):
563 return dict(self)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000564
Skip Montanaro289bc052007-08-17 02:30:27 +0000565 def setdefault(self, key, value):
566 if key not in self:
567 self[key] = value
568 return self[key]
569
570try:
571 _putenv = putenv
572except NameError:
573 _putenv = lambda key, value: None
Martin v. Löwisa90f4382001-03-07 09:05:45 +0000574else:
Skip Montanaro289bc052007-08-17 02:30:27 +0000575 __all__.append("putenv")
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000576
Skip Montanaro289bc052007-08-17 02:30:27 +0000577try:
578 _unsetenv = unsetenv
579except NameError:
580 _unsetenv = lambda key: _putenv(key, "")
581else:
582 __all__.append("unsetenv")
Guido van Rossumc524d952001-10-19 01:31:59 +0000583
Victor Stinner84ae1182010-05-06 22:05:07 +0000584def _createenviron():
585 if name in ('os2', 'nt'):
586 # Where Env Var Names Must Be UPPERCASE
587 def check_str(value):
588 if not isinstance(value, str):
589 raise TypeError("str expected, not %s" % type(value).__name__)
590 return value
591 encode = check_str
592 decode = str
593 def encodekey(key):
594 return encode(key).upper()
595 data = {}
596 for key, value in environ.items():
597 data[encodekey(key)] = value
598 else:
599 # Where Env Var Names Can Be Mixed Case
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000600 encoding = sys.getfilesystemencoding()
Victor Stinner84ae1182010-05-06 22:05:07 +0000601 def encode(value):
602 if not isinstance(value, str):
603 raise TypeError("str expected, not %s" % type(value).__name__)
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000604 return value.encode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000605 def decode(value):
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000606 return value.decode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000607 encodekey = encode
608 data = environ
609 return _Environ(data,
610 encodekey, decode,
611 encode, decode,
612 _putenv, _unsetenv)
Guido van Rossumc524d952001-10-19 01:31:59 +0000613
Victor Stinner84ae1182010-05-06 22:05:07 +0000614# unicode environ
615environ = _createenviron()
616del _createenviron
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000617
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000618
Jack Jansenb11ce9b2003-01-08 16:33:40 +0000619def getenv(key, default=None):
Tim Peters2c60f7a2003-01-29 03:49:43 +0000620 """Get an environment variable, return None if it doesn't exist.
Victor Stinner84ae1182010-05-06 22:05:07 +0000621 The optional second argument can specify an alternate default.
622 key, default and the result are str."""
Tim Peters2c60f7a2003-01-29 03:49:43 +0000623 return environ.get(key, default)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000624
Victor Stinnerb745a742010-05-18 17:17:23 +0000625supports_bytes_environ = name not in ('os2', 'nt')
626__all__.extend(("getenv", "supports_bytes_environ"))
627
628if supports_bytes_environ:
Victor Stinner84ae1182010-05-06 22:05:07 +0000629 def _check_bytes(value):
630 if not isinstance(value, bytes):
631 raise TypeError("bytes expected, not %s" % type(value).__name__)
632 return value
633
634 # bytes environ
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000635 environb = _Environ(environ._data,
Victor Stinner84ae1182010-05-06 22:05:07 +0000636 _check_bytes, bytes,
637 _check_bytes, bytes,
638 _putenv, _unsetenv)
639 del _check_bytes
640
641 def getenvb(key, default=None):
642 """Get an environment variable, return None if it doesn't exist.
643 The optional second argument can specify an alternate default.
644 key, default and the result are bytes."""
645 return environb.get(key, default)
Victor Stinner70120e22010-07-29 17:19:38 +0000646
647 __all__.extend(("environb", "getenvb"))
Victor Stinner84ae1182010-05-06 22:05:07 +0000648
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000649def _fscodec():
650 encoding = sys.getfilesystemencoding()
651 if encoding == 'mbcs':
Victor Stinnere882aac2010-10-24 21:12:26 +0000652 errors = 'strict'
Victor Stinner313a1202010-06-11 23:56:51 +0000653 else:
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000654 errors = 'surrogateescape'
Victor Stinnere8d51452010-08-19 01:05:19 +0000655
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000656 def fsencode(filename):
657 """
658 Encode filename to the filesystem encoding with 'surrogateescape' error
659 handler, return bytes unchanged. On Windows, use 'strict' error handler if
660 the file system encoding is 'mbcs' (which is the default encoding).
661 """
662 if isinstance(filename, bytes):
663 return filename
664 elif isinstance(filename, str):
665 return filename.encode(encoding, errors)
Victor Stinnere8d51452010-08-19 01:05:19 +0000666 else:
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000667 raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
668
669 def fsdecode(filename):
670 """
671 Decode filename from the filesystem encoding with 'surrogateescape' error
672 handler, return str unchanged. On Windows, use 'strict' error handler if
673 the file system encoding is 'mbcs' (which is the default encoding).
674 """
675 if isinstance(filename, str):
676 return filename
677 elif isinstance(filename, bytes):
678 return filename.decode(encoding, errors)
679 else:
680 raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
681
682 return fsencode, fsdecode
683
684fsencode, fsdecode = _fscodec()
685del _fscodec
Victor Stinner449c4662010-05-08 11:10:09 +0000686
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000687# Supply spawn*() (probably only for Unix)
688if _exists("fork") and not _exists("spawnv") and _exists("execv"):
689
690 P_WAIT = 0
691 P_NOWAIT = P_NOWAITO = 1
692
693 # XXX Should we support P_DETACH? I suppose it could fork()**2
694 # and close the std I/O streams. Also, P_OVERLAY is the same
695 # as execv*()?
696
697 def _spawnvef(mode, file, args, env, func):
698 # Internal helper; func is the exec*() function to use
699 pid = fork()
700 if not pid:
701 # Child
702 try:
703 if env is None:
704 func(file, args)
705 else:
706 func(file, args, env)
707 except:
708 _exit(127)
709 else:
710 # Parent
711 if mode == P_NOWAIT:
712 return pid # Caller is responsible for waiting!
713 while 1:
714 wpid, sts = waitpid(pid, 0)
715 if WIFSTOPPED(sts):
716 continue
717 elif WIFSIGNALED(sts):
718 return -WTERMSIG(sts)
719 elif WIFEXITED(sts):
720 return WEXITSTATUS(sts)
721 else:
Collin Winter828f04a2007-08-31 00:04:24 +0000722 raise error("Not stopped, signaled or exited???")
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000723
724 def spawnv(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000725 """spawnv(mode, file, args) -> integer
726
727Execute file with arguments from args in a subprocess.
728If mode == P_NOWAIT return the pid of the process.
729If mode == P_WAIT return the process's exit code if it exits normally;
Tim Peters2344fae2001-01-15 00:50:52 +0000730otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000731 return _spawnvef(mode, file, args, None, execv)
732
733 def spawnve(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000734 """spawnve(mode, file, args, env) -> integer
735
736Execute file with arguments from args in a subprocess with the
737specified environment.
738If mode == P_NOWAIT return the pid of the process.
739If mode == P_WAIT return the process's exit code if it exits normally;
740otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000741 return _spawnvef(mode, file, args, env, execve)
742
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000743 # Note: spawnvp[e] is't currently supported on Windows
744
745 def spawnvp(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000746 """spawnvp(mode, file, args) -> integer
747
748Execute file (which is looked for along $PATH) with arguments from
749args in a subprocess.
750If mode == P_NOWAIT return the pid of the process.
751If mode == P_WAIT return the process's exit code if it exits normally;
752otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000753 return _spawnvef(mode, file, args, None, execvp)
754
755 def spawnvpe(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000756 """spawnvpe(mode, file, args, env) -> integer
757
758Execute file (which is looked for along $PATH) with arguments from
759args in a subprocess with the supplied environment.
760If mode == P_NOWAIT return the pid of the process.
761If mode == P_WAIT return the process's exit code if it exits normally;
762otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000763 return _spawnvef(mode, file, args, env, execvpe)
764
765if _exists("spawnv"):
766 # These aren't supplied by the basic Windows code
767 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000768
769 def spawnl(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000770 """spawnl(mode, file, *args) -> integer
771
772Execute file with arguments from args in a subprocess.
773If mode == P_NOWAIT return the pid of the process.
774If mode == P_WAIT return the process's exit code if it exits normally;
775otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000776 return spawnv(mode, file, args)
777
778 def spawnle(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000779 """spawnle(mode, file, *args, env) -> integer
780
781Execute file with arguments from args in a subprocess with the
782supplied environment.
783If mode == P_NOWAIT return the pid of the process.
784If mode == P_WAIT return the process's exit code if it exits normally;
785otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000786 env = args[-1]
787 return spawnve(mode, file, args[:-1], env)
788
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000789
790 __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
791
792
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000793if _exists("spawnvp"):
794 # At the moment, Windows doesn't implement spawnvp[e],
795 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000796 def spawnlp(mode, file, *args):
Neal Norwitzb7f68102003-07-02 02:49:33 +0000797 """spawnlp(mode, file, *args) -> integer
Guido van Rossume0cd2912000-04-21 18:35:36 +0000798
799Execute file (which is looked for along $PATH) with arguments from
800args in a subprocess with the supplied environment.
801If mode == P_NOWAIT return the pid of the process.
802If mode == P_WAIT return the process's exit code if it exits normally;
803otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000804 return spawnvp(mode, file, args)
805
806 def spawnlpe(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000807 """spawnlpe(mode, file, *args, env) -> integer
808
809Execute file (which is looked for along $PATH) with arguments from
810args in a subprocess with the supplied environment.
811If mode == P_NOWAIT return the pid of the process.
812If mode == P_WAIT return the process's exit code if it exits normally;
813otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000814 env = args[-1]
815 return spawnvpe(mode, file, args[:-1], env)
Guido van Rossume0cd2912000-04-21 18:35:36 +0000816
817
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000818 __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
Skip Montanaro269b83b2001-02-06 01:07:02 +0000819
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000820import copyreg as _copyreg
Michael W. Hudson0e025302002-03-06 17:11:18 +0000821
822def _make_stat_result(tup, dict):
823 return stat_result(tup, dict)
824
825def _pickle_stat_result(sr):
826 (type, args) = sr.__reduce__()
827 return (_make_stat_result, args)
828
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000829try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000830 _copyreg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000831except NameError: # stat_result may not exist
832 pass
Michael W. Hudson0e025302002-03-06 17:11:18 +0000833
834def _make_statvfs_result(tup, dict):
835 return statvfs_result(tup, dict)
836
837def _pickle_statvfs_result(sr):
838 (type, args) = sr.__reduce__()
839 return (_make_statvfs_result, args)
840
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000841try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000842 _copyreg.pickle(statvfs_result, _pickle_statvfs_result,
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000843 _make_statvfs_result)
Michael W. Hudsone5363b72002-03-15 10:21:59 +0000844except NameError: # statvfs_result may not exist
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000845 pass
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000846
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000847# Supply os.popen()
Antoine Pitrou877766d2011-03-19 17:00:37 +0100848def popen(cmd, mode="r", buffering=-1):
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000849 if not isinstance(cmd, str):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000850 raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
851 if mode not in ("r", "w"):
852 raise ValueError("invalid mode %r" % mode)
Antoine Pitrou877766d2011-03-19 17:00:37 +0100853 if buffering == 0 or buffering == None:
854 raise ValueError("popen() does not support unbuffered streams")
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000855 import subprocess, io
856 if mode == "r":
857 proc = subprocess.Popen(cmd,
858 shell=True,
859 stdout=subprocess.PIPE,
860 bufsize=buffering)
861 return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
862 else:
863 proc = subprocess.Popen(cmd,
864 shell=True,
865 stdin=subprocess.PIPE,
866 bufsize=buffering)
867 return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
868
869# Helper for popen() -- a proxy for a file whose close waits for the process
870class _wrap_close:
871 def __init__(self, stream, proc):
872 self._stream = stream
873 self._proc = proc
874 def close(self):
875 self._stream.close()
Amaury Forgeot d'Arc97e5f282009-07-11 09:35:13 +0000876 returncode = self._proc.wait()
877 if returncode == 0:
878 return None
879 if name == 'nt':
880 return returncode
881 else:
882 return returncode << 8 # Shift left to match old behavior
Antoine Pitrouac625352009-12-09 00:01:27 +0000883 def __enter__(self):
884 return self
885 def __exit__(self, *args):
886 self.close()
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000887 def __getattr__(self, name):
888 return getattr(self._stream, name)
Thomas Heller476157b2007-09-04 11:27:47 +0000889 def __iter__(self):
890 return iter(self._stream)
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000891
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +0000892# Supply os.fdopen()
893def fdopen(fd, *args, **kwargs):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000894 if not isinstance(fd, int):
895 raise TypeError("invalid fd type (%s, expected integer)" % type(fd))
896 import io
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +0000897 return io.open(fd, *args, **kwargs)