source: trunk/essentials/dev-lang/python/Lib/os.py@ 3403

Last change on this file since 3403 was 3403, checked in by bird, 19 years ago

emx_link wasn't found or something. drop it.

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