blob: dfb4017c10346ede17628c1afd7e5cf4bec6439d [file] [log] [blame]
Tor Norbye3a2425a2013-11-04 10:16:08 -08001r"""OS routines for Mac, NT, or Posix depending on what system we're on.
2
3This exports:
4 - all functions from posix, nt, os2, or ce, e.g. unlink, stat, etc.
5 - os.path is one of the modules posixpath, or ntpath
6 - os.name is 'posix', 'nt', 'os2', 'ce' or 'riscos'
7 - 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 '\\')
10 - os.extsep is the extension separator ('.' or '/')
11 - os.altsep is the alternate pathname separator (None or '/')
12 - os.pathsep is the component separator used in $PATH etc
13 - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
14 - os.defpath is the default search path for executables
15 - os.devnull is the file path of the null device ('/dev/null', etc.)
16
17Programs 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"""
23
24#'
25
26import sys, errno
27
28_names = sys.builtin_module_names
29
30# Note: more names are added to __all__ later.
31__all__ = ["altsep", "curdir", "pardir", "sep", "extsep", "pathsep", "linesep",
32 "defpath", "name", "path", "devnull",
33 "SEEK_SET", "SEEK_CUR", "SEEK_END"]
34
35def _get_exports_list(module):
36 try:
37 return list(module.__all__)
38 except AttributeError:
39 return [n for n in dir(module) if n[0] != '_']
40
41name = 'java'
42if 'posix' in _names:
43 _name = 'posix'
44 linesep = '\n'
45 from posix import *
46 try:
47 from posix import _exit
48 except ImportError:
49 pass
50 import posixpath as path
51
52 import posix
53 __all__.extend(_get_exports_list(posix))
54 del posix
55
56elif 'nt' in _names:
57 _name = 'nt'
58 linesep = '\r\n'
59 from nt import *
60 try:
61 from nt import _exit
62 except ImportError:
63 pass
64 import ntpath as path
65
66 import nt
67 __all__.extend(_get_exports_list(nt))
68 del nt
69
70elif 'os2' in _names:
71 _name = 'os2'
72 linesep = '\r\n'
73 from os2 import *
74 try:
75 from os2 import _exit
76 except ImportError:
77 pass
78 if sys.version.find('EMX GCC') == -1:
79 import ntpath as path
80 else:
81 import os2emxpath as path
82 from _emx_link import link
83
84 import os2
85 __all__.extend(_get_exports_list(os2))
86 del os2
87
88elif 'ce' in _names:
89 _name = 'ce'
90 linesep = '\r\n'
91 from ce import *
92 try:
93 from ce import _exit
94 except ImportError:
95 pass
96 # We can use the standard Windows path.
97 import ntpath as path
98
99 import ce
100 __all__.extend(_get_exports_list(ce))
101 del ce
102
103elif 'riscos' in _names:
104 _name = 'riscos'
105 linesep = '\n'
106 from riscos import *
107 try:
108 from riscos import _exit
109 except ImportError:
110 pass
111 import riscospath as path
112
113 import riscos
114 __all__.extend(_get_exports_list(riscos))
115 del riscos
116
117else:
118 raise ImportError, 'no os specific module found'
119
120sys.modules['os.path'] = path
121from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
122 devnull)
123
124del _names
125
126# Python uses fixed values for the SEEK_ constants; they are mapped
127# to native constants if necessary in posixmodule.c
128SEEK_SET = 0
129SEEK_CUR = 1
130SEEK_END = 2
131
132#'
133
134# Super directory utilities.
135# (Inspired by Eric Raymond; the doc strings are mostly his)
136
137def makedirs(name, mode=0777):
138 """makedirs(path [, mode=0777])
139
140 Super-mkdir; create a leaf directory and all intermediate ones.
141 Works like mkdir, except that any intermediate path segment (not
142 just the rightmost) will be created if it does not exist. This is
143 recursive.
144
145 """
146 head, tail = path.split(name)
147 if not tail:
148 head, tail = path.split(head)
149 if head and tail and not path.exists(head):
150 try:
151 makedirs(head, mode)
152 except OSError, e:
153 # be happy if someone already created the path
154 if e.errno != errno.EEXIST:
155 raise
156 if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists
157 return
158 mkdir(name, mode)
159
160def removedirs(name):
161 """removedirs(path)
162
163 Super-rmdir; remove a leaf directory and all empty intermediate
164 ones. Works like rmdir except that, if the leaf directory is
165 successfully removed, directories corresponding to rightmost path
166 segments will be pruned away until either the whole path is
167 consumed or an error occurs. Errors during this latter phase are
168 ignored -- they generally mean that a directory was not empty.
169
170 """
171 rmdir(name)
172 head, tail = path.split(name)
173 if not tail:
174 head, tail = path.split(head)
175 while head and tail:
176 try:
177 rmdir(head)
178 except error:
179 break
180 head, tail = path.split(head)
181
182def renames(old, new):
183 """renames(old, new)
184
185 Super-rename; create directories as necessary and delete any left
186 empty. Works like rename, except creation of any intermediate
187 directories needed to make the new pathname good is attempted
188 first. After the rename, directories corresponding to rightmost
189 path segments of the old name will be pruned way until either the
190 whole path is consumed or a nonempty directory is found.
191
192 Note: this function can fail with the new directory structure made
193 if you lack permissions needed to unlink the leaf directory or
194 file.
195
196 """
197 head, tail = path.split(new)
198 if head and tail and not path.exists(head):
199 makedirs(head)
200 rename(old, new)
201 head, tail = path.split(old)
202 if head and tail:
203 try:
204 removedirs(head)
205 except error:
206 pass
207
208__all__.extend(["makedirs", "removedirs", "renames"])
209
210def walk(top, topdown=True, onerror=None, followlinks=False):
211 """Directory tree generator.
212
213 For each directory in the directory tree rooted at top (including top
214 itself, but excluding '.' and '..'), yields a 3-tuple
215
216 dirpath, dirnames, filenames
217
218 dirpath is a string, the path to the directory. dirnames is a list of
219 the names of the subdirectories in dirpath (excluding '.' and '..').
220 filenames is a list of the names of the non-directory files in dirpath.
221 Note that the names in the lists are just names, with no path components.
222 To get a full path (which begins with top) to a file or directory in
223 dirpath, do os.path.join(dirpath, name).
224
225 If optional arg 'topdown' is true or not specified, the triple for a
226 directory is generated before the triples for any of its subdirectories
227 (directories are generated top down). If topdown is false, the triple
228 for a directory is generated after the triples for all of its
229 subdirectories (directories are generated bottom up).
230
231 When topdown is true, the caller can modify the dirnames list in-place
232 (e.g., via del or slice assignment), and walk will only recurse into the
233 subdirectories whose names remain in dirnames; this can be used to prune
234 the search, or to impose a specific order of visiting. Modifying
235 dirnames when topdown is false is ineffective, since the directories in
236 dirnames have already been generated by the time dirnames itself is
237 generated.
238
239 By default errors from the os.listdir() call are ignored. If
240 optional arg 'onerror' is specified, it should be a function; it
241 will be called with one argument, an os.error instance. It can
242 report the error to continue with the walk, or raise the exception
243 to abort the walk. Note that the filename is available as the
244 filename attribute of the exception object.
245
246 By default, os.walk does not follow symbolic links to subdirectories on
247 systems that support them. In order to get this functionality, set the
248 optional argument 'followlinks' to true.
249
250 Caution: if you pass a relative pathname for top, don't change the
251 current working directory between resumptions of walk. walk never
252 changes the current directory, and assumes that the client doesn't
253 either.
254
255 Example:
256
257 import os
258 from os.path import join, getsize
259 for root, dirs, files in os.walk('python/Lib/email'):
260 print root, "consumes",
261 print sum([getsize(join(root, name)) for name in files]),
262 print "bytes in", len(files), "non-directory files"
263 if 'CVS' in dirs:
264 dirs.remove('CVS') # don't visit CVS directories
265 """
266
267 from os.path import join, isdir, islink
268
269 # We may not have read permission for top, in which case we can't
270 # get a list of the files the directory contains. os.path.walk
271 # always suppressed the exception then, rather than blow up for a
272 # minor reason when (say) a thousand readable directories are still
273 # left to visit. That logic is copied here.
274 try:
275 # Note that listdir and error are globals in this module due
276 # to earlier import-*.
277 names = listdir(top)
278 except error, err:
279 if onerror is not None:
280 onerror(err)
281 return
282
283 dirs, nondirs = [], []
284 for name in names:
285 if isdir(join(top, name)):
286 dirs.append(name)
287 else:
288 nondirs.append(name)
289
290 if topdown:
291 yield top, dirs, nondirs
292 for name in dirs:
293 path = join(top, name)
294 if followlinks or not islink(path):
295 for x in walk(path, topdown, onerror, followlinks):
296 yield x
297 if not topdown:
298 yield top, dirs, nondirs
299
300__all__.append("walk")
301
302# Make sure os.environ exists, at least
303try:
304 environ
305except NameError:
306 environ = {}
307
308def _exists(name):
309 # CPython eval's the name, whereas looking in __all__ works for
310 # Jython and is much faster
311 return name in __all__
312
313if _exists('execv'):
314
315 def execl(file, *args):
316 """execl(file, *args)
317
318 Execute the executable file with argument list args, replacing the
319 current process. """
320 execv(file, args)
321
322 def execle(file, *args):
323 """execle(file, *args, env)
324
325 Execute the executable file with argument list args and
326 environment env, replacing the current process. """
327 env = args[-1]
328 execve(file, args[:-1], env)
329
330 def execlp(file, *args):
331 """execlp(file, *args)
332
333 Execute the executable file (which is searched for along $PATH)
334 with argument list args, replacing the current process. """
335 execvp(file, args)
336
337 def execlpe(file, *args):
338 """execlpe(file, *args, env)
339
340 Execute the executable file (which is searched for along $PATH)
341 with argument list args and environment env, replacing the current
342 process. """
343 env = args[-1]
344 execvpe(file, args[:-1], env)
345
346 def execvp(file, args):
347 """execp(file, args)
348
349 Execute the executable file (which is searched for along $PATH)
350 with argument list args, replacing the current process.
351 args may be a list or tuple of strings. """
352 _execvpe(file, args)
353
354 def execvpe(file, args, env):
355 """execvpe(file, args, env)
356
357 Execute the executable file (which is searched for along $PATH)
358 with argument list args and environment env , replacing the
359 current process.
360 args may be a list or tuple of strings. """
361 _execvpe(file, args, env)
362
363 __all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
364
365 def _execvpe(file, args, env=None):
366 if env is not None:
367 func = execve
368 argrest = (args, env)
369 else:
370 func = execv
371 argrest = (args,)
372 env = environ
373
374 head, tail = path.split(file)
375 if head:
376 func(file, *argrest)
377 return
378 if 'PATH' in env:
379 envpath = env['PATH']
380 else:
381 envpath = defpath
382 PATH = envpath.split(pathsep)
383 saved_exc = None
384 saved_tb = None
385 for dir in PATH:
386 fullname = path.join(dir, file)
387 try:
388 func(fullname, *argrest)
389 except error, e:
390 tb = sys.exc_info()[2]
391 if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR
392 and saved_exc is None):
393 saved_exc = e
394 saved_tb = tb
395 if saved_exc:
396 raise error, saved_exc, saved_tb
397 raise error, e, tb
398
399# Change environ to automatically call putenv() if it exists
400try:
401 # This will fail if there's no putenv
402 putenv
403except NameError:
404 pass
405else:
406 # Fake unsetenv() for Windows
407 # not sure about os2 here but
408 # I'm guessing they are the same.
409
410 if name in ('os2', 'nt'):
411 def unsetenv(key):
412 putenv(key, "")
413
414 if _name == "riscos":
415 # On RISC OS, all env access goes through getenv and putenv
416 from riscosenviron import _Environ
417 elif _name in ('os2', 'nt'): # Where Env Var Names Must Be UPPERCASE
418 import UserDict
419
420 # But we store them as upper case
421 class _Environ(UserDict.IterableUserDict):
422 def __init__(self, environ):
423 UserDict.UserDict.__init__(self)
424 data = self.data
425 for k, v in environ.items():
426 data[k.upper()] = v
427 def __setitem__(self, key, item):
428 self.data[key.upper()] = item
429 def __getitem__(self, key):
430 return self.data[key.upper()]
431 def __delitem__(self, key):
432 del self.data[key.upper()]
433 def has_key(self, key):
434 return key.upper() in self.data
435 def __contains__(self, key):
436 return key.upper() in self.data
437 def get(self, key, failobj=None):
438 return self.data.get(key.upper(), failobj)
439 def update(self, dict=None, **kwargs):
440 if dict:
441 try:
442 keys = dict.keys()
443 except AttributeError:
444 # List of (key, value)
445 for k, v in dict:
446 self[k] = v
447 else:
448 # got keys
449 # cannot use items(), since mappings
450 # may not have them.
451 for k in keys:
452 self[k] = dict[k]
453 if kwargs:
454 self.update(kwargs)
455 def copy(self):
456 return dict(self)
457
458 environ = _Environ(environ)
459
460def getenv(key, default=None):
461 """Get an environment variable, return None if it doesn't exist.
462 The optional second argument can specify an alternate default."""
463 return environ.get(key, default)
464__all__.append("getenv")
465
466# Supply spawn*() (probably only for Unix)
467if _exists("fork") and not _exists("spawnv") and _exists("execv"):
468
469 P_WAIT = 0
470 P_NOWAIT = P_NOWAITO = 1
471
472 # XXX Should we support P_DETACH? I suppose it could fork()**2
473 # and close the std I/O streams. Also, P_OVERLAY is the same
474 # as execv*()?
475
476 def _spawnvef(mode, file, args, env, func):
477 # Internal helper; func is the exec*() function to use
478 pid = fork()
479 if not pid:
480 # Child
481 try:
482 if env is None:
483 func(file, args)
484 else:
485 func(file, args, env)
486 except:
487 _exit(127)
488 else:
489 # Parent
490 if mode == P_NOWAIT:
491 return pid # Caller is responsible for waiting!
492 while 1:
493 wpid, sts = waitpid(pid, 0)
494 if WIFSTOPPED(sts):
495 continue
496 elif WIFSIGNALED(sts):
497 return -WTERMSIG(sts)
498 elif WIFEXITED(sts):
499 return WEXITSTATUS(sts)
500 else:
501 raise error, "Not stopped, signaled or exited???"
502
503 def spawnv(mode, file, args):
504 """spawnv(mode, file, args) -> integer
505
506Execute file with arguments from args in a subprocess.
507If mode == P_NOWAIT return the pid of the process.
508If mode == P_WAIT return the process's exit code if it exits normally;
509otherwise return -SIG, where SIG is the signal that killed it. """
510 return _spawnvef(mode, file, args, None, execv)
511
512 def spawnve(mode, file, args, env):
513 """spawnve(mode, file, args, env) -> integer
514
515Execute file with arguments from args in a subprocess with the
516specified environment.
517If mode == P_NOWAIT return the pid of the process.
518If mode == P_WAIT return the process's exit code if it exits normally;
519otherwise return -SIG, where SIG is the signal that killed it. """
520 return _spawnvef(mode, file, args, env, execve)
521
522 # Note: spawnvp[e] is't currently supported on Windows
523
524 def spawnvp(mode, file, args):
525 """spawnvp(mode, file, args) -> integer
526
527Execute file (which is looked for along $PATH) with arguments from
528args in a subprocess.
529If mode == P_NOWAIT return the pid of the process.
530If mode == P_WAIT return the process's exit code if it exits normally;
531otherwise return -SIG, where SIG is the signal that killed it. """
532 return _spawnvef(mode, file, args, None, execvp)
533
534 def spawnvpe(mode, file, args, env):
535 """spawnvpe(mode, file, args, env) -> integer
536
537Execute file (which is looked for along $PATH) with arguments from
538args in a subprocess with the supplied environment.
539If mode == P_NOWAIT return the pid of the process.
540If mode == P_WAIT return the process's exit code if it exits normally;
541otherwise return -SIG, where SIG is the signal that killed it. """
542 return _spawnvef(mode, file, args, env, execvpe)
543
544if _exists("spawnv"):
545 # These aren't supplied by the basic Windows code
546 # but can be easily implemented in Python
547
548 def spawnl(mode, file, *args):
549 """spawnl(mode, file, *args) -> integer
550
551Execute file with arguments from args in a subprocess.
552If mode == P_NOWAIT return the pid of the process.
553If mode == P_WAIT return the process's exit code if it exits normally;
554otherwise return -SIG, where SIG is the signal that killed it. """
555 return spawnv(mode, file, args)
556
557 def spawnle(mode, file, *args):
558 """spawnle(mode, file, *args, env) -> integer
559
560Execute file with arguments from args in a subprocess with the
561supplied environment.
562If mode == P_NOWAIT return the pid of the process.
563If mode == P_WAIT return the process's exit code if it exits normally;
564otherwise return -SIG, where SIG is the signal that killed it. """
565 env = args[-1]
566 return spawnve(mode, file, args[:-1], env)
567
568
569 __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
570
571
572if _exists("spawnvp"):
573 # At the moment, Windows doesn't implement spawnvp[e],
574 # so it won't have spawnlp[e] either.
575 def spawnlp(mode, file, *args):
576 """spawnlp(mode, file, *args) -> integer
577
578Execute file (which is looked for along $PATH) with arguments from
579args in a subprocess with the supplied environment.
580If mode == P_NOWAIT return the pid of the process.
581If mode == P_WAIT return the process's exit code if it exits normally;
582otherwise return -SIG, where SIG is the signal that killed it. """
583 return spawnvp(mode, file, args)
584
585 def spawnlpe(mode, file, *args):
586 """spawnlpe(mode, file, *args, env) -> integer
587
588Execute file (which is looked for along $PATH) with arguments from
589args in a subprocess with the supplied environment.
590If mode == P_NOWAIT return the pid of the process.
591If mode == P_WAIT return the process's exit code if it exits normally;
592otherwise return -SIG, where SIG is the signal that killed it. """
593 env = args[-1]
594 return spawnvpe(mode, file, args[:-1], env)
595
596
597 __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
598
599
600# Supply popen2 etc. (for Unix)
601if sys.platform.startswith('java') or _exists("fork"):
602 if not _exists("popen2"):
603 def popen2(cmd, mode="t", bufsize=-1):
604 """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd'
605 may be a sequence, in which case arguments will be passed directly to
606 the program without shell intervention (as with os.spawnv()). If 'cmd'
607 is a string it will be passed to the shell (as with os.system()). If
608 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
609 file objects (child_stdin, child_stdout) are returned."""
610 import subprocess
611 PIPE = subprocess.PIPE
612 p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
613 bufsize=bufsize, stdin=PIPE, stdout=PIPE,
614 close_fds=True)
615 return p.stdin, p.stdout
616 __all__.append("popen2")
617
618 if not _exists("popen3"):
619 def popen3(cmd, mode="t", bufsize=-1):
620 """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd'
621 may be a sequence, in which case arguments will be passed directly to
622 the program without shell intervention (as with os.spawnv()). If 'cmd'
623 is a string it will be passed to the shell (as with os.system()). If
624 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
625 file objects (child_stdin, child_stdout, child_stderr) are returned."""
626 import subprocess
627 PIPE = subprocess.PIPE
628 p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
629 bufsize=bufsize, stdin=PIPE, stdout=PIPE,
630 stderr=PIPE, close_fds=True)
631 return p.stdin, p.stdout, p.stderr
632 __all__.append("popen3")
633
634 if not _exists("popen4"):
635 def popen4(cmd, mode="t", bufsize=-1):
636 """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd'
637 may be a sequence, in which case arguments will be passed directly to
638 the program without shell intervention (as with os.spawnv()). If 'cmd'
639 is a string it will be passed to the shell (as with os.system()). If
640 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
641 file objects (child_stdin, child_stdout_stderr) are returned."""
642 import subprocess
643 PIPE = subprocess.PIPE
644 p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
645 bufsize=bufsize, stdin=PIPE, stdout=PIPE,
646 stderr=subprocess.STDOUT, close_fds=True)
647 return p.stdin, p.stdout
648 __all__.append("popen4")
649
650if not _exists("urandom"):
651 def urandom(n):
652 """urandom(n) -> str
653
654 Return a string of n random bytes suitable for cryptographic use.
655
656 """
657 try:
658 _urandomfd = open("/dev/urandom", O_RDONLY)
659 except (OSError, IOError):
660 raise NotImplementedError("/dev/urandom (or equivalent) not found")
661 bytes = ""
662 while len(bytes) < n:
663 bytes += read(_urandomfd, n - len(bytes))
664 close(_urandomfd)
665 return bytes
666
667# Supply os.popen()
668def popen(cmd, mode='r', bufsize=-1):
669 """popen(command [, mode='r' [, bufsize]]) -> pipe
670
671 Open a pipe to/from a command returning a file object.
672 """
673 if not isinstance(cmd, (str, unicode)):
674 raise TypeError('invalid cmd type (%s, expected string)' % type(cmd))
675 if mode not in ('r', 'w'):
676 raise ValueError("invalid mode %r" % mode)
677 import subprocess
678 if mode == 'r':
679 proc = subprocess.Popen(cmd, bufsize=bufsize, shell=True,
680 stdout=subprocess.PIPE)
681 fp = proc.stdout
682 elif mode == 'w':
683 proc = subprocess.Popen(cmd, bufsize=bufsize, shell=True,
684 stdin=subprocess.PIPE)
685 fp = proc.stdin
686 # files from subprocess are in binary mode but popen needs text mode
687 fp = fdopen(fp.fileno(), mode, bufsize)
688 return _wrap_close(fp, proc)
689
690# Helper for popen() -- a proxy for a file whose close waits for the process
691class _wrap_close(object):
692 def __init__(self, stream, proc):
693 self._stream = stream
694 self._proc = proc
695 def close(self):
696 self._stream.close()
697 returncode = self._proc.wait()
698 if returncode == 0:
699 return None
700 if _name == 'nt':
701 return returncode
702 else:
703 return returncode
704 def __getattr__(self, name):
705 return getattr(self._stream, name)
706 def __iter__(self):
707 return iter(self._stream)