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