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