From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <2ab73cd1648cacbfd32cf6a4d0b4b698@plan9.bell-labs.com> From: "Russ Cox" To: 9fans@cse.psu.edu Subject: Re: [9fans] to Russ Cox (others may read, too ;-) [sorry, long] MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Date: Wed, 3 Apr 2002 11:14:53 -0500 Topicbox-Message-UUID: 72677902-eaca-11e9-9e20-41e7f4b1d025 Do you have these two files, os.py and plan9.py, in /sys/lib/python? # To unbundle, run this file echo os.py sed 's/.//' >os.py <<'//GO.SYSIN DD os.py' -r"""OS routines for Mac, DOS, NT, or Posix depending on what system we're on. - -This exports: - - all functions from posix, nt, dos, os2, mac, or ce, e.g. unlink, stat, etc. - - os.path is one of the modules posixpath, ntpath, macpath, or dospath - - os.name is 'posix', 'nt', 'dos', 'os2', 'mac', 'ce', 'riscos', or 'plan9' - - os.curdir is a string representing the current directory ('.' or ':') - - os.pardir is a string representing the parent directory ('..' or '::') - - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\') - - os.extsep is the extension separator ('.' or '/') - - os.altsep is the alternate pathname separator (None or '/') - - os.pathsep is the component separator used in $PATH etc - - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n') - - os.defpath is the default search path for executables - -Programs that import and use 'os' stand a better chance of being -portable between different platforms. Of course, they must then -only use functions that are defined by all platforms (e.g., unlink -and opendir), and leave all pathname manipulation to os.path -(e.g., split and join). -""" - -#' - -import sys - -_names = sys.builtin_module_names - -altsep = None - -__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep", - "defpath", "name"] - -def _get_exports_list(module): - try: - return list(module.__all__) - except AttributeError: - return [n for n in dir(module) if n[0] != '_'] - -if 'posix' in _names: - name = 'posix' - linesep = '\n' - curdir = '.'; pardir = '..'; sep = '/'; pathsep = ':' - defpath = ':/bin:/usr/bin' - from posix import * - try: - from posix import _exit - except ImportError: - pass - import posixpath - path = posixpath - del posixpath - - import posix - __all__.extend(_get_exports_list(posix)) - del posix - -elif 'nt' in _names: - name = 'nt' - linesep = '\r\n' - curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';' - defpath = '.;C:\\bin' - from nt import * - for i in ['_exit']: - try: - exec "from nt import " + i - except ImportError: - pass - import ntpath - path = ntpath - del ntpath - - import nt - __all__.extend(_get_exports_list(nt)) - del nt - -elif 'dos' in _names: - name = 'dos' - linesep = '\r\n' - curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';' - defpath = '.;C:\\bin' - from dos import * - try: - from dos import _exit - except ImportError: - pass - import dospath - path = dospath - del dospath - - import dos - __all__.extend(_get_exports_list(dos)) - del dos - -elif 'os2' in _names: - name = 'os2' - linesep = '\r\n' - curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';' - defpath = '.;C:\\bin' - from os2 import * - try: - from os2 import _exit - except ImportError: - pass - import ntpath - path = ntpath - del ntpath - - import os2 - __all__.extend(_get_exports_list(os2)) - del os2 - -elif 'mac' in _names: - name = 'mac' - linesep = '\r' - curdir = ':'; pardir = '::'; sep = ':'; pathsep = '\n' - defpath = ':' - from mac import * - try: - from mac import _exit - except ImportError: - pass - import macpath - path = macpath - del macpath - - import mac - __all__.extend(_get_exports_list(mac)) - del mac - -elif 'ce' in _names: - name = 'ce' - linesep = '\r\n' - curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';' - defpath = '\\Windows' - from ce import * - for i in ['_exit']: - try: - exec "from ce import " + i - except ImportError: - pass - # We can use the standard Windows path. - import ntpath - path = ntpath - del ntpath - - import ce - __all__.extend(_get_exports_list(ce)) - del ce - -elif 'riscos' in _names: - name = 'riscos' - linesep = '\n' - curdir = '@'; pardir = '^'; sep = '.'; pathsep = ',' - defpath = '' - from riscos import * - try: - from riscos import _exit - except ImportError: - pass - import riscospath - path = riscospath - del riscospath - - import riscos - __all__.extend(_get_exports_list(riscos)) - del riscos - -elif '_plan9' in _names: - name = 'plan9' - linesep = '\n' - curdir = '.'; pardir = '..'; sep = '/' - import plan9 - from plan9 import * - try: - from plan9 import _exit - except ImportError: - pass - stat = osstat - dup2 = dup - dup = osdup - execvp = plan9._exec - getcwd = getwd - getpgrp = getnoteid - getuid = getuser - getlogin = getuser - unlink = remove - import plan9path as path - __all__.extend(_get_exports_list(plan9)) - del plan9 - -else: - raise ImportError, 'no os specific module found' - - -if sep=='.': - extsep = '/' -else: - extsep = '.' - -__all__.append("path") - -del _names - -sys.modules['os.path'] = path - -#' - -# Super directory utilities. -# (Inspired by Eric Raymond; the doc strings are mostly his) - -def makedirs(name, mode=0777): - """makedirs(path [, mode=0777]) -> None - - Super-mkdir; create a leaf directory and all intermediate ones. - Works like mkdir, except that any intermediate path segment (not - just the rightmost) will be created if it does not exist. This is - recursive. - - """ - head, tail = path.split(name) - if not tail: - head, tail = path.split(head) - if head and tail and not path.exists(head): - makedirs(head, mode) - mkdir(name, mode) - -def removedirs(name): - """removedirs(path) -> None - - Super-rmdir; remove a leaf directory and empty all intermediate - ones. Works like rmdir except that, if the leaf directory is - successfully removed, directories corresponding to rightmost path - segments will be pruned way until either the whole path is - consumed or an error occurs. Errors during this latter phase are - ignored -- they generally mean that a directory was not empty. - - """ - rmdir(name) - head, tail = path.split(name) - if not tail: - head, tail = path.split(head) - while head and tail: - try: - rmdir(head) - except error: - break - head, tail = path.split(head) - -def renames(old, new): - """renames(old, new) -> None - - Super-rename; create directories as necessary and delete any left - empty. Works like rename, except creation of any intermediate - directories needed to make the new pathname good is attempted - first. After the rename, directories corresponding to rightmost - path segments of the old name will be pruned way until either the - whole path is consumed or a nonempty directory is found. - - Note: this function can fail with the new directory structure made - if you lack permissions needed to unlink the leaf directory or - file. - - """ - head, tail = path.split(new) - if head and tail and not path.exists(head): - makedirs(head) - rename(old, new) - head, tail = path.split(old) - if head and tail: - try: - removedirs(head) - except error: - pass - -__all__.extend(["makedirs", "removedirs", "renames"]) - -# Make sure os.environ exists, at least -try: - environ -except NameError: - environ = {} - -def execl(file, *args): - """execl(file, *args) - - Execute the executable file with argument list args, replacing the - current process. """ - execv(file, args) - -def execle(file, *args): - """execle(file, *args, env) - - Execute the executable file with argument list args and - environment env, replacing the current process. """ - env = args[-1] - execve(file, args[:-1], env) - -def execlp(file, *args): - """execlp(file, *args) - - Execute the executable file (which is searched for along $PATH) - with argument list args, replacing the current process. """ - execvp(file, args) - -def execlpe(file, *args): - """execlpe(file, *args, env) - - Execute the executable file (which is searched for along $PATH) - with argument list args and environment env, replacing the current - process. """ - env = args[-1] - execvpe(file, args[:-1], env) - -def execvp(file, args): - """execp(file, args) - - Execute the executable file (which is searched for along $PATH) - with argument list args, replacing the current process. - args may be a list or tuple of strings. """ - _execvpe(file, args) - -def execvpe(file, args, env): - """execv(file, args, env) - - Execute the executable file (which is searched for along $PATH) - with argument list args and environment env , replacing the - current process. - args may be a list or tuple of strings. """ - _execvpe(file, args, env) - -__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"]) - -_notfound = None -def _execvpe(file, args, env=None): - if env is not None: - func = execve - argrest = (args, env) - else: - func = execv - argrest = (args,) - env = environ - global _notfound - head, tail = path.split(file) - if head: - apply(func, (file,) + argrest) - return - if env.has_key('PATH'): - envpath = env['PATH'] - else: - envpath = defpath - PATH = envpath.split(pathsep) - if not _notfound: - if sys.platform[:4] == 'beos': - # Process handling (fork, wait) under BeOS (up to 5.0) - # doesn't interoperate reliably with the thread interlocking - # that happens during an import. The actual error we need - # is the same on BeOS for posix.open() et al., ENOENT. - try: unlink('/_#.# ## #.#') - except error, _notfound: pass - else: - import tempfile - t = tempfile.mktemp() - # Exec a file that is guaranteed not to exist - try: execv(t, ('blah',)) - except error, _notfound: pass - exc, arg = error, _notfound - for dir in PATH: - fullname = path.join(dir, file) - try: - apply(func, (fullname,) + argrest) - except error, (errno, msg): - if errno != arg[0]: - exc, arg = error, (errno, msg) - raise exc, arg - - -# Change environ to automatically call putenv() if it exists -try: - # This will fail if there's no putenv - putenv -except NameError: - pass -else: - import UserDict - - # Fake unsetenv() for Windows - # not sure about os2 and dos here but - # I'm guessing they are the same. - - if name in ('os2', 'nt', 'dos'): - def unsetenv(key): - putenv(key, "") - - if name == "riscos": - # On RISC OS, all env access goes through getenv and putenv - from riscosenviron import _Environ - elif name in ('os2', 'nt', 'dos'): # Where Env Var Names Must Be UPPERCASE - # But we store them as upper case - class _Environ(UserDict.UserDict): - def __init__(self, environ): - UserDict.UserDict.__init__(self) - data = self.data - for k, v in environ.items(): - data[k.upper()] = v - def __setitem__(self, key, item): - putenv(key, item) - self.data[key.upper()] = item - def __getitem__(self, key): - return self.data[key.upper()] - try: - unsetenv - except NameError: - def __delitem__(self, key): - del self.data[key.upper()] - else: - def __delitem__(self, key): - unsetenv(key) - del self.data[key.upper()] - def has_key(self, key): - return self.data.has_key(key.upper()) - def get(self, key, failobj=None): - return self.data.get(key.upper(), failobj) - def update(self, dict): - for k, v in dict.items(): - self[k] = v - - else: # Where Env Var Names Can Be Mixed Case - class _Environ(UserDict.UserDict): - def __init__(self, environ): - UserDict.UserDict.__init__(self) - self.data = environ - def __setitem__(self, key, item): - putenv(key, item) - self.data[key] = item - def update(self, dict): - for k, v in dict.items(): - self[k] = v - try: - unsetenv - except NameError: - pass - else: - def __delitem__(self, key): - unsetenv(key) - del self.data[key] - - - environ = _Environ(environ) - - def getenv(key, default=None): - """Get an environment variable, return None if it doesn't exist. - The optional second argument can specify an alternate default.""" - return environ.get(key, default) - __all__.append("getenv") - -def _exists(name): - try: - eval(name) - return 1 - except NameError: - return 0 - -# Supply spawn*() (probably only for Unix) -if _exists("fork") and not _exists("spawnv") and _exists("execv"): - - P_WAIT = 0 - P_NOWAIT = P_NOWAITO = 1 - - # XXX Should we support P_DETACH? I suppose it could fork()**2 - # and close the std I/O streams. Also, P_OVERLAY is the same - # as execv*()? - - def _spawnvef(mode, file, args, env, func): - # Internal helper; func is the exec*() function to use - pid = fork() - if not pid: - # Child - try: - if env is None: - func(file, args) - else: - func(file, args, env) - except: - _exit(127) - else: - # Parent - if mode == P_NOWAIT: - return pid # Caller is responsible for waiting! - while 1: - wpid, sts = waitpid(pid, 0) - if WIFSTOPPED(sts): - continue - elif WIFSIGNALED(sts): - return -WTERMSIG(sts) - elif WIFEXITED(sts): - return WEXITSTATUS(sts) - else: - raise error, "Not stopped, signaled or exited???" - - def spawnv(mode, file, args): - """spawnv(mode, file, args) -> integer - -Execute file with arguments from args in a subprocess. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - return _spawnvef(mode, file, args, None, execv) - - def spawnve(mode, file, args, env): - """spawnve(mode, file, args, env) -> integer - -Execute file with arguments from args in a subprocess with the -specified environment. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - return _spawnvef(mode, file, args, env, execve) - - # Note: spawnvp[e] is't currently supported on Windows - - def spawnvp(mode, file, args): - """spawnvp(mode, file, args) -> integer - -Execute file (which is looked for along $PATH) with arguments from -args in a subprocess. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - return _spawnvef(mode, file, args, None, execvp) - - def spawnvpe(mode, file, args, env): - """spawnvpe(mode, file, args, env) -> integer - -Execute file (which is looked for along $PATH) with arguments from -args in a subprocess with the supplied environment. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - return _spawnvef(mode, file, args, env, execvpe) - -if _exists("spawnv"): - # These aren't supplied by the basic Windows code - # but can be easily implemented in Python - - def spawnl(mode, file, *args): - """spawnl(mode, file, *args) -> integer - -Execute file with arguments from args in a subprocess. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - return spawnv(mode, file, args) - - def spawnle(mode, file, *args): - """spawnle(mode, file, *args, env) -> integer - -Execute file with arguments from args in a subprocess with the -supplied environment. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - env = args[-1] - return spawnve(mode, file, args[:-1], env) - -if _exists("spawnvp"): - # At the moment, Windows doesn't implement spawnvp[e], - # so it won't have spawnlp[e] either. - def spawnlp(mode, file, *args): - """spawnlp(mode, file, *args, env) -> integer - -Execute file (which is looked for along $PATH) with arguments from -args in a subprocess with the supplied environment. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - return spawnvp(mode, file, args) - - def spawnlpe(mode, file, *args): - """spawnlpe(mode, file, *args, env) -> integer - -Execute file (which is looked for along $PATH) with arguments from -args in a subprocess with the supplied environment. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - env = args[-1] - return spawnvpe(mode, file, args[:-1], env) - - - __all__.extend(["spawnlp","spawnlpe","spawnv", "spawnve","spawnvp", - "spawnvpe","spawnl","spawnle",]) - - -# Supply popen2 etc. (for Unix) -if _exists("fork"): - if not _exists("popen2"): - def popen2(cmd, mode="t", bufsize=-1): - import popen2 - stdout, stdin = popen2.popen2(cmd, bufsize) - return stdin, stdout - __all__.append("popen2") - - if not _exists("popen3"): - def popen3(cmd, mode="t", bufsize=-1): - import popen2 - stdout, stdin, stderr = popen2.popen3(cmd, bufsize) - return stdin, stdout, stderr - __all__.append("popen3") - - if not _exists("popen4"): - def popen4(cmd, mode="t", bufsize=-1): - import popen2 - stdout, stdin = popen2.popen4(cmd, bufsize) - return stdin, stdout - __all__.append("popen4") //GO.SYSIN DD os.py echo plan9.py sed 's/.//' >plan9.py <<'//GO.SYSIN DD plan9.py' -"""OS routines for Plan 9 from Bell Labs - -System calls are implemented by the _plan9 module. -Various wrappers are provided here. - -""" - -from _plan9 import * -from _plan9 import _exits, _exec -import string - -MORDER = 0x0003 # mask for bits defining order of mounting -MREPL = 0x0000 # mount replaces object -MBEFORE = 0x0001 # mount goes before others in union -MAFTER = 0x0002 # mount goes after others in union -MCREATE = 0x0004 # permit creation in mounted directory -MCACHE = 0x0010 # cache some data -MMASK = 0x0017 # all bits on - -OREAD = 0 # open for read -OWRITE = 1 # write -ORDWR = 2 # read and write -OEXEC = 3 # execute, == read but check execute permission -OTRUNC = 16 # or'ed in (except for exec), truncate file first -OCEXEC = 32 # or'ed in, close on exec -ORCLOSE = 64 # or'ed in, remove on close -OEXCL = 0x1000 # or'ed in, exclusive use (create only) - -AEXIST = 0 # accessible: exists -AEXEC = 1 # execute access -AWRITE = 2 # write access -AREAD = 4 # read access - -QTDIR = 0x80 # type bit for directories -QTAPPEND = 0x40 # type bit for append only files -QTEXCL = 0x20 # type bit for exclusive use files -QTMOUNT = 0x10 # type bit for mounted channel -QTAUTH = 0x08 # type bit for authentication file -QTFILE = 0x00 # plan file - -DMDIR = 0x80000000 # mode bit for directories -DMAPPEND = 0x40000000 # mode bit for append only files -DMEXCL = 0x20000000 # mode bit for exclusive use files -DMMOUNT = 0x10000000 # mode bit for mounted channel -DMAUTH = 0x08000000 # mode bit for authentication file -DMREAD = 0x4 # mode bit for read permission -DMWRITE = 0x2 # mode bit for write permission -DMEXEC = 0x1 # mode bit for execute permission - -RFNAMEG = 1<<0 # new name space group -RFENVG = 1<<1 # new environment group -RFFDG = 1<<2 # new file descriptor group -RFNOTEG = 1<<3 # new note group -RFPROC = 1<<4 # new process -RFMEM = 1<<5 # share memory -RFNOWAIT = 1<<6 # don't generate wait message for new process -RFCNAMEG = 1<<10 # clear name space -RFCENVG = 1<<11 # clear environment -RFCFDG = 1<<12 # clear file descriptors -RFREND = 1<<13 # new rendezvous group -RFNOMNT = 1<<14 # don't allow child to mount - -class Qid: - def __init__(self): - self.path1 = 0L - self.vers = 0 - self.type = 0 - - def fromtuple(self, x): - self.path = x[0] - self.vers = x[1] - self.type = x[2] - return self - - def totuple(self): - return (self.path, self.vers, self.type) - - def __repr__(self): - return '' % (self.path, self.vers, self.type) - -class Dir: - def __init__(self): - self.type = -1 - self.dev = '\x80' - self.qid = Qid().fromtuple((-1, -1, 0xFF)) - self.mode = -1 - self.atime = -1 - self.mtime = -1 - self.length = -1 - self.name = '' - self.uid = '' - self.gid = '' - self.muid = '' - - def fromtuple(self, x): - d = Dir() - d.name = x[0] - d.qid = Qid().fromtuple(x[1]) - d.dev = x[2][0] - d.type = x[2][1] - d.mode = x[3] - d.atime = x[4] - d.mtime = x[5] - d.length = x[6] - d.uid = x[7] - d.gid = x[8] - d.muid = x[9] - return d - - def totuple(self): - return (self.name, self.qid.totuple(), (self.dev, self.type), self.mode, self.atime, \ - self.mtime, self.length, self.uid, self.gid, self.muid) - - def __repr__(self): - return '' % \ - (self.name, str(self.qid), self.dev, self.type, self.mode, self.atime, \ - self.mtime, self.length, self.uid, self.gid, self.muid) - -class Waitmsg: - def __init__(self): - self.pid = -1 - self.utime = 0 - self.stime = 0 - self.rtime = 0 - self.msg = '' - - def fromtuple(self, x): - self.pid = x[0] - self.utime = x[1] - self.stime = x[2] - self.rtime = x[3] - self.msg = x[4] - return self - - def totuple(self): - return (self.pid, self.utime, self.stime, self.rtime, self.msg) - - def __repr__(self): - return '' % self.totuple() - -def dirstat(path): - return Dir().fromtuple(stat(path)) - -def dirwstat(path, dir): - return wstat(path, dir.totuple()) - -def dirfstat(fd): - return Dir().fromtuple(fstat(fd)) - -def dirfwstat(fd, dir): - return fwstat(fd, dir.totuple()) - -def fork(): - return rfork(RFFDG|RFREND|RFPROC) - -# getcwd defined as getwd in os.py - -# getlogin defined as getuser in os.py - -def getnoteid(): - return string.atoi(readfile("/proc/"+`getpid()`+"/noteid")) - -# getpgrp defined as getnoteid in os.py - -def getpid(): - return string.atoi(readfile("/dev/pid")) - -def getppid(): - return string.atoi(readfile("/dev/ppid")) - -# getuid defined as getuser in os.py - -def getuser(): - return readfile("/dev/user") - -def getwd(): - try: - fd = -1 - fd = open(".", OREAD) - s = fd2path(fd) - close(fd) - return s - except: - close(fd) - raise - -def isatty(fd): - s = fd2path(fd); - return len(s)>=9 and s[-9:]=='/dev/cons' - -# there are file descriptor leaks in all the popen routines -# error cases. also, does f=fdopen(fd); f.close() close fd? - -def popen(cmd, mode='r', bufsize=-1): - if mode != 'r' and mode != 'w': - raise ValueError('bad mode '+mode); - t = pipe() - pid = rfork(RFFDG|RFPROC|RFNOWAIT) - if pid == 0: - try: - close(t[1]) - if mode == 'r': - dup(t[0], 1) - else: - dup(t[0], 0) - _exec('/bin/rc', ['rc', '-c', cmd]) - except Exception, msg: - _exits(msg) - else: - close(t[0]) - return fdopen(t[0], mode, bufsize) - -def popen2(cmd, mode='t', bufsize=-1): - t = pipe() - u = pipe() - pid = rfork(RFFDG|RFPROC|RFNOWAIT) - if pid == 0: - try: - close(t[1]) - close(u[1]) - dup(t[0], 0) - dup(u[0], 1) - _exec('/bin/rc', ['rc', '-c', cmd]) - except Exception, msg: - _exits(msg) - else: - close(t[0]) - close(u[0]) - return fdopen(t[1], 'w', bufsize), fdopen(u[1], 'r', bufsize) - -def popen3(cmd, mode='t', bufsize=-1): - t = pipe() - u = pipe() - v = pipe() - pid = rfork(RFFDG|RFPROC|RFNOWAIT) - if pid == 0: - try: - close(t[1]) - close(u[1]) - close(v[1]) - dup(t[0], 0) - dup(u[0], 1) - dup(v[0], 2) - _exec('/bin/rc', ['rc', '-c', cmd]) - except Exception, msg: - _exits(msg) - else: - close(t[0]) - close(u[0]) - close(v[0]) - return fdopen(t[1], 'w', bufsize), fdopen(u[1], 'r', bufsize), fdopen(v[1], 'r', bufsize) - -def popen4(cmd, mode='t', bufsize=-1): - t = pipe() - u = pipe() - pid = rfork(RFFDG|RFPROC|RFNOWAIT) - if pid == 0: - try: - close(t[1]) - close(u[1]) - dup(t[0], 0) - dup(u[0], 1) - dup(u[0], 2) - _exec('/bin/rc', ['rc', '-c', cmd]) - except Exception, msg: - _exits(msg) - else: - close(t[0]) - close(u[0]) - close(v[0]) - return fdopen(t[1], 'w', bufsize), fdopen(u[1], 'r', bufsize) - -def read(fd, len): - return pread(fd, len, -1L) - -def readfile(path): - fd = open(path, OREAD) - tot = '' - try: - s = read(fd, 1024) - while s != '': - tot += s - s = read(fd, 1024) - except: - close(fd) - raise - close(fd) - return tot - -def readn(fd, m): - tot = '' - s = read(fd, m) - while s != '': - tot += s - s = read(fd, m - len(tot)) - return tot - -def _splitpath(p): - t = string.rfind(p, "/")+1 - if t == 0: - return (".", p) - return (p[0:t], p[t:]) - -def rename(old, new): - (odir, oname) = _splitpath(old) - (ndir, nname) = _splitpath(new) - if odir != ndir: - raise ValueError, "rename from dir "+odir+" to "+ndir - d=Dir() - d.name = nname - return wstat(old, d.totuple()) - -def sysname(): - return readfile("/env/sysname") - -def time(): - return string.atoi(tokenize(readfile("/dev/time"))[0]) - -def tokenize(s): - return gettokens(s, " \t\r\n") - -def write(fd, s): - return pwrite(fd, s, -1L) - -def wait(): - return Waitmsg().fromtuple(tokenize(await())) - -def waitpid(): - return string.atoi(tokenize(await())[0]) - -# Implementations for the Posix module to import - -def osstat(p): - x = stat(p) - return (x[3], x[1][1], x[2][0], 1, x[7], x[8], x[6], x[4], x[5], 0) - -def osdup(fd): - return dup(fd, -1) - -def listdir(p): - l = dirreadall(p) - return map(lambda x:x[0], l) - -def uname(): - try: - node=readfile("/dev/sysname") - except: - node="gnot" - try: - release="9P"+tokenize(readfile("/dev/osversion"))[0] - except: - release="9P1" - try: - version=readfile("/env/terminal") - except: - version="" - try: - version+=readfile("/env/bootfile") - except: - pass - try: - machine=readfile("/env/cputype") - except: - machine="unknown" - return ("Plan 9", node, release, version, machine) //GO.SYSIN DD plan9.py