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, 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
117elif 'ibmi' in _names:
118    _name = 'ibmi'
119    linesep = '\n'
120    from ibmi import *
121    try:
122        from ibmi import _exit
123    except ImportError:
124        pass
125    import posixpath as path
126
127    import ibmi
128    __all__.extend(_get_exports_list(ibmi))
129    del ibmi
130
131else:
132    raise ImportError, 'no os specific module found'
133
134sys.modules['os.path'] = path
135from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
136    devnull)
137
138del _names
139
140# Python uses fixed values for the SEEK_ constants; they are mapped
141# to native constants if necessary in posixmodule.c
142SEEK_SET = 0
143SEEK_CUR = 1
144SEEK_END = 2
145
146#'
147
148# Super directory utilities.
149# (Inspired by Eric Raymond; the doc strings are mostly his)
150
151def makedirs(name, mode=0777):
152    """makedirs(path [, mode=0777])
153
154    Super-mkdir; create a leaf directory and all intermediate ones.
155    Works like mkdir, except that any intermediate path segment (not
156    just the rightmost) will be created if it does not exist.  This is
157    recursive.
158
159    """
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 != 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, followlinks=False):
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    By default, os.walk does not follow symbolic links to subdirectories on
261    systems that support them.  In order to get this functionality, set the
262    optional argument 'followlinks' to true.
263
264    Caution:  if you pass a relative pathname for top, don't change the
265    current working directory between resumptions of walk.  walk never
266    changes the current directory, and assumes that the client doesn't
267    either.
268
269    Example:
270
271    import os
272    from os.path import join, getsize
273    for root, dirs, files in os.walk('python/Lib/email'):
274        print root, "consumes",
275        print sum([getsize(join(root, name)) for name in files]),
276        print "bytes in", len(files), "non-directory files"
277        if 'CVS' in dirs:
278            dirs.remove('CVS')  # don't visit CVS directories
279    """
280
281    from os.path import join, isdir, islink
282
283    # We may not have read permission for top, in which case we can't
284    # get a list of the files the directory contains.  os.path.walk
285    # always suppressed the exception then, rather than blow up for a
286    # minor reason when (say) a thousand readable directories are still
287    # left to visit.  That logic is copied here.
288    try:
289        # Note that listdir and error are globals in this module due
290        # to earlier import-*.
291        names = listdir(top)
292    except error, err:
293        if onerror is not None:
294            onerror(err)
295        return
296
297    dirs, nondirs = [], []
298    for name in names:
299        if isdir(join(top, name)):
300            dirs.append(name)
301        else:
302            nondirs.append(name)
303
304    if topdown:
305        yield top, dirs, nondirs
306    for name in dirs:
307        path = join(top, name)
308        if followlinks or not islink(path):
309            for x in walk(path, topdown, onerror, followlinks):
310                yield x
311    if not topdown:
312        yield top, dirs, nondirs
313
314__all__.append("walk")
315
316# Make sure os.environ exists, at least
317try:
318    environ
319except NameError:
320    environ = {}
321
322def _exists(name):
323    # CPython eval's the name, whereas looking in __all__ works for
324    # Jython and is much faster
325    return name in __all__
326
327if _exists('execv'):
328
329    def execl(file, *args):
330        """execl(file, *args)
331
332        Execute the executable file with argument list args, replacing the
333        current process. """
334        execv(file, args)
335
336    def execle(file, *args):
337        """execle(file, *args, env)
338
339        Execute the executable file with argument list args and
340        environment env, replacing the current process. """
341        env = args[-1]
342        execve(file, args[:-1], env)
343
344    def execlp(file, *args):
345        """execlp(file, *args)
346
347        Execute the executable file (which is searched for along $PATH)
348        with argument list args, replacing the current process. """
349        execvp(file, args)
350
351    def execlpe(file, *args):
352        """execlpe(file, *args, env)
353
354        Execute the executable file (which is searched for along $PATH)
355        with argument list args and environment env, replacing the current
356        process. """
357        env = args[-1]
358        execvpe(file, args[:-1], env)
359
360    def execvp(file, args):
361        """execp(file, args)
362
363        Execute the executable file (which is searched for along $PATH)
364        with argument list args, replacing the current process.
365        args may be a list or tuple of strings. """
366        _execvpe(file, args)
367
368    def execvpe(file, args, env):
369        """execvpe(file, args, env)
370
371        Execute the executable file (which is searched for along $PATH)
372        with argument list args and environment env , replacing the
373        current process.
374        args may be a list or tuple of strings. """
375        _execvpe(file, args, env)
376
377    __all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
378
379    def _execvpe(file, args, env=None):
380        if env is not None:
381            func = execve
382            argrest = (args, env)
383        else:
384            func = execv
385            argrest = (args,)
386            env = environ
387
388        head, tail = path.split(file)
389        if head:
390            func(file, *argrest)
391            return
392        if 'PATH' in env:
393            envpath = env['PATH']
394        else:
395            envpath = defpath
396        PATH = envpath.split(pathsep)
397        saved_exc = None
398        saved_tb = None
399        for dir in PATH:
400            fullname = path.join(dir, file)
401            try:
402                func(fullname, *argrest)
403            except error, e:
404                tb = sys.exc_info()[2]
405                if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR
406                    and saved_exc is None):
407                    saved_exc = e
408                    saved_tb = tb
409        if saved_exc:
410            raise error, saved_exc, saved_tb
411        raise error, e, tb
412
413# Change environ to automatically call putenv() if it exists
414try:
415    # This will fail if there's no putenv
416    putenv
417except NameError:
418    pass
419else:
420    # Fake unsetenv() for Windows
421    # not sure about os2 here but
422    # I'm guessing they are the same.
423
424    if name in ('os2', 'nt'):
425        def unsetenv(key):
426            putenv(key, "")
427
428    if _name == "riscos":
429        # On RISC OS, all env access goes through getenv and putenv
430        from riscosenviron import _Environ
431    elif _name in ('os2', 'nt'):  # Where Env Var Names Must Be UPPERCASE
432        import UserDict
433
434        # But we store them as upper case
435        class _Environ(UserDict.IterableUserDict):
436            def __init__(self, environ):
437                UserDict.UserDict.__init__(self)
438                data = self.data
439                for k, v in environ.items():
440                    data[k.upper()] = v
441            def __setitem__(self, key, item):
442                self.data[key.upper()] = item
443            def __getitem__(self, key):
444                return self.data[key.upper()]
445            def __delitem__(self, key):
446                del self.data[key.upper()]
447            def has_key(self, key):
448                return key.upper() in self.data
449            def __contains__(self, key):
450                return key.upper() in self.data
451            def get(self, key, failobj=None):
452                return self.data.get(key.upper(), failobj)
453            def update(self, dict=None, **kwargs):
454                if dict:
455                    try:
456                        keys = dict.keys()
457                    except AttributeError:
458                        # List of (key, value)
459                        for k, v in dict:
460                            self[k] = v
461                    else:
462                        # got keys
463                        # cannot use items(), since mappings
464                        # may not have them.
465                        for k in keys:
466                            self[k] = dict[k]
467                if kwargs:
468                    self.update(kwargs)
469            def copy(self):
470                return dict(self)
471
472        environ = _Environ(environ)
473
474def getenv(key, default=None):
475    """Get an environment variable, return None if it doesn't exist.
476    The optional second argument can specify an alternate default."""
477    return environ.get(key, default)
478__all__.append("getenv")
479
480# Supply spawn*() (probably only for Unix)
481if _exists("fork") and not _exists("spawnv") and _exists("execv"):
482
483    P_WAIT = 0
484    P_NOWAIT = P_NOWAITO = 1
485
486    # XXX Should we support P_DETACH?  I suppose it could fork()**2
487    # and close the std I/O streams.  Also, P_OVERLAY is the same
488    # as execv*()?
489
490    def _spawnvef(mode, file, args, env, func):
491        # Internal helper; func is the exec*() function to use
492        pid = fork()
493        if not pid:
494            # Child
495            try:
496                if env is None:
497                    func(file, args)
498                else:
499                    func(file, args, env)
500            except:
501                _exit(127)
502        else:
503            # Parent
504            if mode == P_NOWAIT:
505                return pid # Caller is responsible for waiting!
506            while 1:
507                wpid, sts = waitpid(pid, 0)
508                if WIFSTOPPED(sts):
509                    continue
510                elif WIFSIGNALED(sts):
511                    return -WTERMSIG(sts)
512                elif WIFEXITED(sts):
513                    return WEXITSTATUS(sts)
514                else:
515                    raise error, "Not stopped, signaled or exited???"
516
517    def spawnv(mode, file, args):
518        """spawnv(mode, file, args) -> integer
519
520Execute file with arguments from args in a subprocess.
521If mode == P_NOWAIT return the pid of the process.
522If mode == P_WAIT return the process's exit code if it exits normally;
523otherwise return -SIG, where SIG is the signal that killed it. """
524        return _spawnvef(mode, file, args, None, execv)
525
526    def spawnve(mode, file, args, env):
527        """spawnve(mode, file, args, env) -> integer
528
529Execute file with arguments from args in a subprocess with the
530specified environment.
531If mode == P_NOWAIT return the pid of the process.
532If mode == P_WAIT return the process's exit code if it exits normally;
533otherwise return -SIG, where SIG is the signal that killed it. """
534        return _spawnvef(mode, file, args, env, execve)
535
536    # Note: spawnvp[e] is't currently supported on Windows
537
538    def spawnvp(mode, file, args):
539        """spawnvp(mode, file, args) -> integer
540
541Execute file (which is looked for along $PATH) with arguments from
542args in a subprocess.
543If mode == P_NOWAIT return the pid of the process.
544If mode == P_WAIT return the process's exit code if it exits normally;
545otherwise return -SIG, where SIG is the signal that killed it. """
546        return _spawnvef(mode, file, args, None, execvp)
547
548    def spawnvpe(mode, file, args, env):
549        """spawnvpe(mode, file, args, env) -> integer
550
551Execute file (which is looked for along $PATH) with arguments from
552args in a subprocess with the supplied environment.
553If mode == P_NOWAIT return the pid of the process.
554If mode == P_WAIT return the process's exit code if it exits normally;
555otherwise return -SIG, where SIG is the signal that killed it. """
556        return _spawnvef(mode, file, args, env, execvpe)
557
558if _exists("spawnv"):
559    # These aren't supplied by the basic Windows code
560    # but can be easily implemented in Python
561
562    def spawnl(mode, file, *args):
563        """spawnl(mode, file, *args) -> integer
564
565Execute file with arguments from args in a subprocess.
566If mode == P_NOWAIT return the pid of the process.
567If mode == P_WAIT return the process's exit code if it exits normally;
568otherwise return -SIG, where SIG is the signal that killed it. """
569        return spawnv(mode, file, args)
570
571    def spawnle(mode, file, *args):
572        """spawnle(mode, file, *args, env) -> integer
573
574Execute file with arguments from args in a subprocess with the
575supplied environment.
576If mode == P_NOWAIT return the pid of the process.
577If mode == P_WAIT return the process's exit code if it exits normally;
578otherwise return -SIG, where SIG is the signal that killed it. """
579        env = args[-1]
580        return spawnve(mode, file, args[:-1], env)
581
582
583    __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
584
585
586if _exists("spawnvp"):
587    # At the moment, Windows doesn't implement spawnvp[e],
588    # so it won't have spawnlp[e] either.
589    def spawnlp(mode, file, *args):
590        """spawnlp(mode, file, *args) -> 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 spawnvp(mode, file, args)
598
599    def spawnlpe(mode, file, *args):
600        """spawnlpe(mode, file, *args, env) -> integer
601
602Execute file (which is looked for along $PATH) with arguments from
603args in a subprocess with the supplied environment.
604If mode == P_NOWAIT return the pid of the process.
605If mode == P_WAIT return the process's exit code if it exits normally;
606otherwise return -SIG, where SIG is the signal that killed it. """
607        env = args[-1]
608        return spawnvpe(mode, file, args[:-1], env)
609
610
611    __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
612
613
614# Supply popen2 etc. (for Unix)
615if sys.platform.startswith('java') or _exists("fork"):
616    if not _exists("popen2"):
617        def popen2(cmd, mode="t", bufsize=-1):
618            """Execute the shell command 'cmd' in a sub-process.  On UNIX, 'cmd'
619            may be a sequence, in which case arguments will be passed directly to
620            the program without shell intervention (as with os.spawnv()).  If 'cmd'
621            is a string it will be passed to the shell (as with os.system()). If
622            'bufsize' is specified, it sets the buffer size for the I/O pipes.  The
623            file objects (child_stdin, child_stdout) are returned."""
624            import subprocess
625            PIPE = subprocess.PIPE
626            p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
627                                 bufsize=bufsize, stdin=PIPE, stdout=PIPE,
628                                 close_fds=True)
629            return p.stdin, p.stdout
630        __all__.append("popen2")
631
632    if not _exists("popen3"):
633        def popen3(cmd, mode="t", bufsize=-1):
634            """Execute the shell command 'cmd' in a sub-process.  On UNIX, 'cmd'
635            may be a sequence, in which case arguments will be passed directly to
636            the program without shell intervention (as with os.spawnv()).  If 'cmd'
637            is a string it will be passed to the shell (as with os.system()). If
638            'bufsize' is specified, it sets the buffer size for the I/O pipes.  The
639            file objects (child_stdin, child_stdout, child_stderr) are returned."""
640            import subprocess
641            PIPE = subprocess.PIPE
642            p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
643                                 bufsize=bufsize, stdin=PIPE, stdout=PIPE,
644                                 stderr=PIPE, close_fds=True)
645            return p.stdin, p.stdout, p.stderr
646        __all__.append("popen3")
647
648    if not _exists("popen4"):
649        def popen4(cmd, mode="t", bufsize=-1):
650            """Execute the shell command 'cmd' in a sub-process.  On UNIX, 'cmd'
651            may be a sequence, in which case arguments will be passed directly to
652            the program without shell intervention (as with os.spawnv()).  If 'cmd'
653            is a string it will be passed to the shell (as with os.system()). If
654            'bufsize' is specified, it sets the buffer size for the I/O pipes.  The
655            file objects (child_stdin, child_stdout_stderr) are returned."""
656            import subprocess
657            PIPE = subprocess.PIPE
658            p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
659                                 bufsize=bufsize, stdin=PIPE, stdout=PIPE,
660                                 stderr=subprocess.STDOUT, close_fds=True)
661            return p.stdin, p.stdout
662        __all__.append("popen4")
663
664if not _exists("urandom"):
665    def urandom(n):
666        """urandom(n) -> str
667
668        Return a string of n random bytes suitable for cryptographic use.
669
670        """
671        try:
672            _urandomfd = open("/dev/urandom", O_RDONLY)
673        except (OSError, IOError):
674            raise NotImplementedError("/dev/urandom (or equivalent) not found")
675        bytes = ""
676        while len(bytes) < n:
677            bytes += read(_urandomfd, n - len(bytes))
678        close(_urandomfd)
679        return bytes
680
681# Supply os.popen()
682def popen(cmd, mode='r', bufsize=-1):
683    """popen(command [, mode='r' [, bufsize]]) -> pipe
684
685    Open a pipe to/from a command returning a file object.
686    """
687    if not isinstance(cmd, (str, unicode)):
688        raise TypeError('invalid cmd type (%s, expected string)' % type(cmd))
689    if mode not in ('r', 'w'):
690        raise ValueError("invalid mode %r" % mode)
691    import subprocess
692    if mode == 'r':
693        proc = subprocess.Popen(cmd, bufsize=bufsize, shell=True,
694                                stdout=subprocess.PIPE)
695        fp = proc.stdout
696    elif mode == 'w':
697        proc = subprocess.Popen(cmd, bufsize=bufsize, shell=True,
698                                stdin=subprocess.PIPE)
699        fp = proc.stdin
700    # files from subprocess are in binary mode but popen needs text mode
701    fp = fdopen(fp.fileno(), mode, bufsize)
702    return _wrap_close(fp, proc)
703
704# Helper for popen() -- a proxy for a file whose close waits for the process
705class _wrap_close(object):
706    def __init__(self, stream, proc):
707        self._stream = stream
708        self._proc = proc
709    def close(self):
710        self._stream.close()
711        returncode = self._proc.wait()
712        if returncode == 0:
713            return None
714        if _name == 'nt':
715            return returncode
716        else:
717            return returncode
718    def __getattr__(self, name):
719        return getattr(self._stream, name)
720    def __iter__(self):
721        return iter(self._stream)
722