os.py revision 7e47402264cf87b9bbb61fc9ff610af08add7c7b
1"""OS routines for Mac, DOS, NT, or Posix depending on what system we're on. 2 3This exports: 4 - all functions from posix, nt, dos, os2, mac, or ce, e.g. unlink, stat, etc. 5 - os.path is one of the modules posixpath, ntpath, macpath, or dospath 6 - os.name is 'posix', 'nt', 'dos', 'os2', 'mac', or 'ce' 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.altsep is the alternate pathname separator (None or '/') 11 - os.pathsep is the component separator used in $PATH etc 12 - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n') 13 - os.defpath is the default search path for executables 14 15Programs that import and use 'os' stand a better chance of being 16portable between different platforms. Of course, they must then 17only use functions that are defined by all platforms (e.g., unlink 18and opendir), and leave all pathname manipulation to os.path 19(e.g., split and join). 20""" 21 22import sys 23 24_names = sys.builtin_module_names 25 26altsep = None 27 28if 'posix' in _names: 29 name = 'posix' 30 linesep = '\n' 31 curdir = '.'; pardir = '..'; sep = '/'; pathsep = ':' 32 defpath = ':/bin:/usr/bin' 33 from posix import * 34 try: 35 from posix import _exit 36 except ImportError: 37 pass 38 import posixpath 39 path = posixpath 40 del posixpath 41elif 'nt' in _names: 42 name = 'nt' 43 linesep = '\r\n' 44 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';' 45 defpath = '.;C:\\bin' 46 from nt import * 47 for i in ['_exit']: 48 try: 49 exec "from nt import " + i 50 except ImportError: 51 pass 52 import ntpath 53 path = ntpath 54 del ntpath 55elif 'dos' in _names: 56 name = 'dos' 57 linesep = '\r\n' 58 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';' 59 defpath = '.;C:\\bin' 60 from dos import * 61 try: 62 from dos import _exit 63 except ImportError: 64 pass 65 import dospath 66 path = dospath 67 del dospath 68elif 'os2' in _names: 69 name = 'os2' 70 linesep = '\r\n' 71 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';' 72 defpath = '.;C:\\bin' 73 from os2 import * 74 try: 75 from os2 import _exit 76 except ImportError: 77 pass 78 import ntpath 79 path = ntpath 80 del ntpath 81elif 'mac' in _names: 82 name = 'mac' 83 linesep = '\r' 84 curdir = ':'; pardir = '::'; sep = ':'; pathsep = '\n' 85 defpath = ':' 86 from mac import * 87 try: 88 from mac import _exit 89 except ImportError: 90 pass 91 import macpath 92 path = macpath 93 del macpath 94elif 'ce' in _names: 95 name = 'ce' 96 linesep = '\r\n' 97 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';' 98 defpath = '\\Windows' 99 from ce import * 100 for i in ['_exit']: 101 try: 102 exec "from ce import " + i 103 except ImportError: 104 pass 105 # We can use the standard Windows path. 106 import ntpath 107 path = ntpath 108 del ntpath 109else: 110 raise ImportError, 'no os specific module found' 111 112del _names 113 114sys.modules['os.path'] = path 115 116# Super directory utilities. 117# (Inspired by Eric Raymond; the doc strings are mostly his) 118 119def makedirs(name, mode=0777): 120 """makedirs(path [, mode=0777]) -> None 121 122 Super-mkdir; create a leaf directory and all intermediate ones. 123 Works like mkdir, except that any intermediate path segment (not 124 just the rightmost) will be created if it does not exist. This is 125 recursive. 126 127 """ 128 head, tail = path.split(name) 129 if head and tail and not path.exists(head): 130 makedirs(head, mode) 131 mkdir(name, mode) 132 133def removedirs(name): 134 """removedirs(path) -> None 135 136 Super-rmdir; remove a leaf directory and empty all intermediate 137 ones. Works like rmdir except that, if the leaf directory is 138 successfully removed, directories corresponding to rightmost path 139 segments will be pruned way until either the whole path is 140 consumed or an error occurs. Errors during this latter phase are 141 ignored -- they generally mean that a directory was not empty. 142 143 """ 144 rmdir(name) 145 head, tail = path.split(name) 146 while head and tail: 147 try: 148 rmdir(head) 149 except error: 150 break 151 head, tail = path.split(head) 152 153def renames(old, new): 154 """renames(old, new) -> None 155 156 Super-rename; create directories as necessary and delete any left 157 empty. Works like rename, except creation of any intermediate 158 directories needed to make the new pathname good is attempted 159 first. After the rename, directories corresponding to rightmost 160 path segments of the old name will be pruned way until either the 161 whole path is consumed or a nonempty directory is found. 162 163 Note: this function can fail with the new directory structure made 164 if you lack permissions needed to unlink the leaf directory or 165 file. 166 167 """ 168 head, tail = path.split(new) 169 if head and tail and not path.exists(head): 170 makedirs(head) 171 rename(old, new) 172 head, tail = path.split(old) 173 if head and tail: 174 try: 175 removedirs(head) 176 except error: 177 pass 178 179# Make sure os.environ exists, at least 180try: 181 environ 182except NameError: 183 environ = {} 184 185def execl(file, *args): 186 """execl(file, *args) 187 188 Execute the executable file with argument list args, replacing the 189 current process. """ 190 execv(file, args) 191 192def execle(file, *args): 193 """execle(file, *args, env) 194 195 Execute the executable file with argument list args and 196 environment env, replacing the current process. """ 197 env = args[-1] 198 execve(file, args[:-1], env) 199 200def execlp(file, *args): 201 """execlp(file, *args) 202 203 Execute the executable file (which is searched for along $PATH) 204 with argument list args, replacing the current process. """ 205 execvp(file, args) 206 207def execlpe(file, *args): 208 """execlpe(file, *args, env) 209 210 Execute the executable file (which is searched for along $PATH) 211 with argument list args and environment env, replacing the current 212 process. """ 213 env = args[-1] 214 execvpe(file, args[:-1], env) 215 216def execvp(file, args): 217 """execp(file, args) 218 219 Execute the executable file (which is searched for along $PATH) 220 with argument list args, replacing the current process. 221 args may be a list or tuple of strings. """ 222 _execvpe(file, args) 223 224def execvpe(file, args, env): 225 """execv(file, args, env) 226 227 Execute the executable file (which is searched for along $PATH) 228 with argument list args and environment env , replacing the 229 current process. 230 args may be a list or tuple of strings. """ 231 _execvpe(file, args, env) 232 233_notfound = None 234def _execvpe(file, args, env=None): 235 if env is not None: 236 func = execve 237 argrest = (args, env) 238 else: 239 func = execv 240 argrest = (args,) 241 env = environ 242 global _notfound 243 head, tail = path.split(file) 244 if head: 245 apply(func, (file,) + argrest) 246 return 247 if env.has_key('PATH'): 248 envpath = env['PATH'] 249 else: 250 envpath = defpath 251 PATH = envpath.split(pathsep) 252 if not _notfound: 253 import tempfile 254 # Exec a file that is guaranteed not to exist 255 try: execv(tempfile.mktemp(), ('blah',)) 256 except error, _notfound: pass 257 exc, arg = error, _notfound 258 for dir in PATH: 259 fullname = path.join(dir, file) 260 try: 261 apply(func, (fullname,) + argrest) 262 except error, (errno, msg): 263 if errno != arg[0]: 264 exc, arg = error, (errno, msg) 265 raise exc, arg 266 267# Change environ to automatically call putenv() if it exists 268try: 269 # This will fail if there's no putenv 270 putenv 271except NameError: 272 pass 273else: 274 import UserDict 275 276 if name in ('os2', 'nt', 'dos'): # Where Env Var Names Must Be UPPERCASE 277 # But we store them as upper case 278 class _Environ(UserDict.UserDict): 279 def __init__(self, environ): 280 UserDict.UserDict.__init__(self) 281 data = self.data 282 for k, v in environ.items(): 283 data[k.upper()] = v 284 def __setitem__(self, key, item): 285 putenv(key, item) 286 self.data[key.upper()] = item 287 def __getitem__(self, key): 288 return self.data[key.upper()] 289 def __delitem__(self, key): 290 del self.data[key.upper()] 291 def has_key(self, key): 292 return self.data.has_key(key.upper()) 293 def get(self, key, failobj=None): 294 return self.data.get(key.upper(), failobj) 295 def update(self, dict): 296 for k, v in dict.items(): 297 self[k] = v 298 299 else: # Where Env Var Names Can Be Mixed Case 300 class _Environ(UserDict.UserDict): 301 def __init__(self, environ): 302 UserDict.UserDict.__init__(self) 303 self.data = environ 304 def __setitem__(self, key, item): 305 putenv(key, item) 306 self.data[key] = item 307 def update(self, dict): 308 for k, v in dict.items(): 309 self[k] = v 310 311 environ = _Environ(environ) 312 313def getenv(key, default=None): 314 """Get an environment variable, return None if it doesn't exist. 315 316 The optional second argument can specify an alternative default.""" 317 return environ.get(key, default) 318 319def _exists(name): 320 try: 321 eval(name) 322 return 1 323 except NameError: 324 return 0 325 326# Supply spawn*() (probably only for Unix) 327if _exists("fork") and not _exists("spawnv") and _exists("execv"): 328 329 P_WAIT = 0 330 P_NOWAIT = P_NOWAITO = 1 331 332 # XXX Should we support P_DETACH? I suppose it could fork()**2 333 # and close the std I/O streams. Also, P_OVERLAY is the same 334 # as execv*()? 335 336 def _spawnvef(mode, file, args, env, func): 337 # Internal helper; func is the exec*() function to use 338 pid = fork() 339 if not pid: 340 # Child 341 try: 342 if env is None: 343 func(file, args) 344 else: 345 func(file, args, env) 346 except: 347 _exit(127) 348 else: 349 # Parent 350 if mode == P_NOWAIT: 351 return pid # Caller is responsible for waiting! 352 while 1: 353 wpid, sts = waitpid(pid, 0) 354 if WIFSTOPPED(sts): 355 continue 356 elif WIFSIGNALED(sts): 357 return -WTERMSIG(sts) 358 elif WIFEXITED(sts): 359 return WEXITSTATUS(sts) 360 else: 361 raise error, "Not stopped, signaled or exited???" 362 363 def spawnv(mode, file, args): 364 """spawnv(mode, file, args) -> integer 365 366Execute file with arguments from args in a subprocess. 367If mode == P_NOWAIT return the pid of the process. 368If mode == P_WAIT return the process's exit code if it exits normally; 369otherwise return -SIG, where SIG is the signal that killed it. """ 370 return _spawnvef(mode, file, args, None, execv) 371 372 def spawnve(mode, file, args, env): 373 """spawnve(mode, file, args, env) -> integer 374 375Execute file with arguments from args in a subprocess with the 376specified environment. 377If mode == P_NOWAIT return the pid of the process. 378If mode == P_WAIT return the process's exit code if it exits normally; 379otherwise return -SIG, where SIG is the signal that killed it. """ 380 return _spawnvef(mode, file, args, env, execve) 381 382 # Note: spawnvp[e] is't currently supported on Windows 383 384 def spawnvp(mode, file, args): 385 """spawnvp(mode, file, args) -> integer 386 387Execute file (which is looked for along $PATH) with arguments from 388args in a subprocess. 389If mode == P_NOWAIT return the pid of the process. 390If mode == P_WAIT return the process's exit code if it exits normally; 391otherwise return -SIG, where SIG is the signal that killed it. """ 392 return _spawnvef(mode, file, args, None, execvp) 393 394 def spawnvpe(mode, file, args, env): 395 """spawnvpe(mode, file, args, env) -> integer 396 397Execute file (which is looked for along $PATH) with arguments from 398args in a subprocess with the supplied environment. 399If mode == P_NOWAIT return the pid of the process. 400If mode == P_WAIT return the process's exit code if it exits normally; 401otherwise return -SIG, where SIG is the signal that killed it. """ 402 return _spawnvef(mode, file, args, env, execvpe) 403 404if _exists("spawnv"): 405 # These aren't supplied by the basic Windows code 406 # but can be easily implemented in Python 407 408 def spawnl(mode, file, *args): 409 """spawnl(mode, file, *args) -> integer 410 411Execute file with arguments from args in a subprocess. 412If mode == P_NOWAIT return the pid of the process. 413If mode == P_WAIT return the process's exit code if it exits normally; 414otherwise return -SIG, where SIG is the signal that killed it. """ 415 return spawnv(mode, file, args) 416 417 def spawnle(mode, file, *args): 418 """spawnle(mode, file, *args, env) -> integer 419 420Execute file with arguments from args in a subprocess with the 421supplied environment. 422If mode == P_NOWAIT return the pid of the process. 423If mode == P_WAIT return the process's exit code if it exits normally; 424otherwise return -SIG, where SIG is the signal that killed it. """ 425 env = args[-1] 426 return spawnve(mode, file, args[:-1], env) 427 428if _exists("spawnvp"): 429 # At the moment, Windows doesn't implement spawnvp[e], 430 # so it won't have spawnlp[e] either. 431 def spawnlp(mode, file, *args): 432 """spawnlp(mode, file, *args, env) -> integer 433 434Execute file (which is looked for along $PATH) with arguments from 435args in a subprocess with the supplied environment. 436If mode == P_NOWAIT return the pid of the process. 437If mode == P_WAIT return the process's exit code if it exits normally; 438otherwise return -SIG, where SIG is the signal that killed it. """ 439 return spawnvp(mode, file, args) 440 441 def spawnlpe(mode, file, *args): 442 """spawnlpe(mode, file, *args, env) -> integer 443 444Execute file (which is looked for along $PATH) with arguments from 445args in a subprocess with the supplied environment. 446If mode == P_NOWAIT return the pid of the process. 447If mode == P_WAIT return the process's exit code if it exits normally; 448otherwise return -SIG, where SIG is the signal that killed it. """ 449 env = args[-1] 450 return spawnvpe(mode, file, args[:-1], env) 451 452 453