Commit cfd74c31 authored by Tim Peters's avatar Tim Peters

Whitespace normalization.

parent 19bb056e
"""An object-oriented interface to .netrc files.""" """An object-oriented interface to .netrc files."""
# Module and documentation by Eric S. Raymond, 21 Dec 1998 # Module and documentation by Eric S. Raymond, 21 Dec 1998
import os, shlex import os, shlex
...@@ -12,7 +12,7 @@ class netrc: ...@@ -12,7 +12,7 @@ class netrc:
self.hosts = {} self.hosts = {}
self.macros = {} self.macros = {}
lexer = shlex.shlex(fp) lexer = shlex.shlex(fp)
# Allows @ in hostnames. Not a big deal... # Allows @ in hostnames. Not a big deal...
lexer.wordchars = lexer.wordchars + '.-@' lexer.wordchars = lexer.wordchars + '.-@'
while 1: while 1:
# Look for a machine, default, or macdef top-level keyword # Look for a machine, default, or macdef top-level keyword
...@@ -23,7 +23,7 @@ class netrc: ...@@ -23,7 +23,7 @@ class netrc:
entryname = lexer.get_token() entryname = lexer.get_token()
elif tt == 'default': elif tt == 'default':
entryname = 'default' entryname = 'default'
elif tt == 'macdef': # Just skip to end of macdefs elif tt == 'macdef': # Just skip to end of macdefs
entryname = lexer.get_token() entryname = lexer.get_token()
self.macros[entryname] = [] self.macros[entryname] = []
lexer.whitepace = ' \t' lexer.whitepace = ' \t'
...@@ -36,7 +36,7 @@ class netrc: ...@@ -36,7 +36,7 @@ class netrc:
self.macros[entryname].append(line) self.macros[entryname].append(line)
else: else:
raise SyntaxError, "bad toplevel token %s, file %s, line %d" \ raise SyntaxError, "bad toplevel token %s, file %s, line %d" \
% (tt, file, lexer.lineno) % (tt, file, lexer.lineno)
# We're looking at start of an entry for a named machine or default. # We're looking at start of an entry for a named machine or default.
if toplevel == 'machine': if toplevel == 'machine':
...@@ -87,6 +87,5 @@ class netrc: ...@@ -87,6 +87,5 @@ class netrc:
rep = rep + "\n" rep = rep + "\n"
return rep return rep
if __name__ == '__main__': if __name__ == '__main__':
print netrc() print netrc()
This diff is collapsed.
# Module 'ntpath' -- common operations on WinNT/Win95 pathnames # Module 'ntpath' -- common operations on WinNT/Win95 pathnames
"""Common pathname manipulations, WindowsNT/95 version. """Common pathname manipulations, WindowsNT/95 version.
Instead of importing this module directly, import os and refer to this Instead of importing this module directly, import os and refer to this
module as os.path. module as os.path.
...@@ -254,7 +254,7 @@ def ismount(path): ...@@ -254,7 +254,7 @@ def ismount(path):
def walk(top, func, arg): def walk(top, func, arg):
"""Directory tree walk whth callback function. """Directory tree walk whth callback function.
walk(top, func, arg) calls func(arg, d, files) for each directory d walk(top, func, arg) calls func(arg, d, files) for each directory d
in the tree rooted at top (including top itself); files is a list in the tree rooted at top (including top itself); files is a list
of all the files and subdirs in directory d.""" of all the files and subdirs in directory d."""
try: try:
...@@ -313,7 +313,7 @@ def expanduser(path): ...@@ -313,7 +313,7 @@ def expanduser(path):
# XXX With COMMAND.COM you can use any characters in a variable name, # XXX With COMMAND.COM you can use any characters in a variable name,
# XXX except '^|<>='. # XXX except '^|<>='.
def expandvars(path): def expandvars(path):
"""Expand shell variables of form $var and ${var}. """Expand shell variables of form $var and ${var}.
Unknown variables are left unchanged.""" Unknown variables are left unchanged."""
......
"""Convert a NT pathname to a file URL and vice versa.""" """Convert a NT pathname to a file URL and vice versa."""
def url2pathname(url): def url2pathname(url):
r"""Convert a URL to a DOS path. r"""Convert a URL to a DOS path.
///C|/foo/bar/spam.foo ///C|/foo/bar/spam.foo
becomes becomes
C:\foo\bar\spam.foo C:\foo\bar\spam.foo
""" """
import string, urllib import string, urllib
if not '|' in url: if not '|' in url:
# No drive specifier, just convert slashes # No drive specifier, just convert slashes
if url[:4] == '////': if url[:4] == '////':
# path is something like ////host/path/on/remote/host # path is something like ////host/path/on/remote/host
# convert this to \\host\path\on\remote\host # convert this to \\host\path\on\remote\host
# (notice halving of slashes at the start of the path) # (notice halving of slashes at the start of the path)
url = url[2:] url = url[2:]
components = string.split(url, '/') components = string.split(url, '/')
# make sure not to convert quoted slashes :-) # make sure not to convert quoted slashes :-)
return urllib.unquote(string.join(components, '\\')) return urllib.unquote(string.join(components, '\\'))
comp = string.split(url, '|') comp = string.split(url, '|')
if len(comp) != 2 or comp[0][-1] not in string.letters: if len(comp) != 2 or comp[0][-1] not in string.letters:
error = 'Bad URL: ' + url error = 'Bad URL: ' + url
raise IOError, error raise IOError, error
drive = string.upper(comp[0][-1]) drive = string.upper(comp[0][-1])
components = string.split(comp[1], '/') components = string.split(comp[1], '/')
path = drive + ':' path = drive + ':'
for comp in components: for comp in components:
if comp: if comp:
path = path + '\\' + urllib.unquote(comp) path = path + '\\' + urllib.unquote(comp)
return path return path
def pathname2url(p): def pathname2url(p):
r"""Convert a DOS path name to a file url. r"""Convert a DOS path name to a file url.
C:\foo\bar\spam.foo C:\foo\bar\spam.foo
becomes becomes
///C|/foo/bar/spam.foo ///C|/foo/bar/spam.foo
""" """
import string, urllib import string, urllib
if not ':' in p: if not ':' in p:
# No drive specifier, just convert slashes and quote the name # No drive specifier, just convert slashes and quote the name
if p[:2] == '\\\\': if p[:2] == '\\\\':
# path is something like \\host\path\on\remote\host # path is something like \\host\path\on\remote\host
# convert this to ////host/path/on/remote/host # convert this to ////host/path/on/remote/host
# (notice doubling of slashes at the start of the path) # (notice doubling of slashes at the start of the path)
p = '\\\\' + p p = '\\\\' + p
components = string.split(p, '\\') components = string.split(p, '\\')
return urllib.quote(string.join(components, '/')) return urllib.quote(string.join(components, '/'))
comp = string.split(p, ':') comp = string.split(p, ':')
if len(comp) != 2 or len(comp[0]) > 1: if len(comp) != 2 or len(comp[0]) > 1:
error = 'Bad path: ' + p error = 'Bad path: ' + p
raise IOError, error raise IOError, error
drive = urllib.quote(string.upper(comp[0])) drive = urllib.quote(string.upper(comp[0]))
components = string.split(comp[1], '\\') components = string.split(comp[1], '\\')
path = '///' + drive + '|' path = '///' + drive + '|'
for comp in components: for comp in components:
if comp: if comp:
path = path + '/' + urllib.quote(comp) path = path + '/' + urllib.quote(comp)
return path return path
...@@ -213,7 +213,7 @@ def execlpe(file, *args): ...@@ -213,7 +213,7 @@ def execlpe(file, *args):
Execute the executable file (which is searched for along $PATH) Execute the executable file (which is searched for along $PATH)
with argument list args and environment env, replacing the current with argument list args and environment env, replacing the current
process. """ process. """
env = args[-1] env = args[-1]
execvpe(file, args[:-1], env) execvpe(file, args[:-1], env)
...@@ -231,7 +231,7 @@ def execvpe(file, args, env): ...@@ -231,7 +231,7 @@ def execvpe(file, args, env):
Execute the executable file (which is searched for along $PATH) Execute the executable file (which is searched for along $PATH)
with argument list args and environment env , replacing the with argument list args and environment env , replacing the
current process. current process.
args may be a list or tuple of strings. """ args may be a list or tuple of strings. """
_execvpe(file, args, env) _execvpe(file, args, env)
_notfound = None _notfound = None
...@@ -370,7 +370,7 @@ if _exists("fork") and not _exists("spawnv") and _exists("execv"): ...@@ -370,7 +370,7 @@ if _exists("fork") and not _exists("spawnv") and _exists("execv"):
Execute file with arguments from args in a subprocess. Execute file with arguments from args in a subprocess.
If mode == P_NOWAIT return the pid of the process. If mode == P_NOWAIT return the pid of the process.
If mode == P_WAIT return the process's exit code if it exits normally; 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. """ otherwise return -SIG, where SIG is the signal that killed it. """
return _spawnvef(mode, file, args, None, execv) return _spawnvef(mode, file, args, None, execv)
def spawnve(mode, file, args, env): def spawnve(mode, file, args, env):
......
This diff is collapsed.
...@@ -123,7 +123,7 @@ class Pickler: ...@@ -123,7 +123,7 @@ class Pickler:
return LONG_BINGET + s return LONG_BINGET + s
return GET + `i` + '\n' return GET + `i` + '\n'
def save(self, object, pers_save = 0): def save(self, object, pers_save = 0):
memo = self.memo memo = self.memo
...@@ -134,7 +134,7 @@ class Pickler: ...@@ -134,7 +134,7 @@ class Pickler:
return return
d = id(object) d = id(object)
t = type(object) t = type(object)
if ((t is TupleType) and (len(object) == 0)): if ((t is TupleType) and (len(object) == 0)):
...@@ -179,14 +179,14 @@ class Pickler: ...@@ -179,14 +179,14 @@ class Pickler:
"tuple" % reduce "tuple" % reduce
l = len(tup) l = len(tup)
if ((l != 2) and (l != 3)): if ((l != 2) and (l != 3)):
raise PicklingError, "tuple returned by %s must contain " \ raise PicklingError, "tuple returned by %s must contain " \
"only two or three elements" % reduce "only two or three elements" % reduce
callable = tup[0] callable = tup[0]
arg_tup = tup[1] arg_tup = tup[1]
if (l > 2): if (l > 2):
state = tup[2] state = tup[2]
else: else:
...@@ -196,7 +196,7 @@ class Pickler: ...@@ -196,7 +196,7 @@ class Pickler:
raise PicklingError, "Second element of tuple returned " \ raise PicklingError, "Second element of tuple returned " \
"by %s must be a tuple" % reduce "by %s must be a tuple" % reduce
self.save_reduce(callable, arg_tup, state) self.save_reduce(callable, arg_tup, state)
memo_len = len(memo) memo_len = len(memo)
self.write(self.put(memo_len)) self.write(self.put(memo_len))
memo[d] = (memo_len, object) memo[d] = (memo_len, object)
...@@ -224,7 +224,7 @@ class Pickler: ...@@ -224,7 +224,7 @@ class Pickler:
save(callable) save(callable)
save(arg_tup) save(arg_tup)
write(REDUCE) write(REDUCE)
if (state is not None): if (state is not None):
save(state) save(state)
write(BUILD) write(BUILD)
...@@ -317,7 +317,7 @@ class Pickler: ...@@ -317,7 +317,7 @@ class Pickler:
if (self.bin): if (self.bin):
write(POP_MARK + self.get(memo[d][0])) write(POP_MARK + self.get(memo[d][0]))
return return
write(POP * (len(object) + 1) + self.get(memo[d][0])) write(POP * (len(object) + 1) + self.get(memo[d][0]))
return return
...@@ -352,7 +352,7 @@ class Pickler: ...@@ -352,7 +352,7 @@ class Pickler:
for element in object: for element in object:
save(element) save(element)
if (not using_appends): if (not using_appends):
write(APPEND) write(APPEND)
...@@ -542,7 +542,7 @@ class Unpickler: ...@@ -542,7 +542,7 @@ class Unpickler:
def load_binpersid(self): def load_binpersid(self):
stack = self.stack stack = self.stack
pid = stack[-1] pid = stack[-1]
del stack[-1] del stack[-1]
...@@ -568,7 +568,7 @@ class Unpickler: ...@@ -568,7 +568,7 @@ class Unpickler:
def load_binint2(self): def load_binint2(self):
self.append(mloads('i' + self.read(2) + '\000\000')) self.append(mloads('i' + self.read(2) + '\000\000'))
dispatch[BININT2] = load_binint2 dispatch[BININT2] = load_binint2
def load_long(self): def load_long(self):
self.append(long(self.readline()[:-1], 0)) self.append(long(self.readline()[:-1], 0))
dispatch[LONG] = load_long dispatch[LONG] = load_long
...@@ -710,7 +710,7 @@ class Unpickler: ...@@ -710,7 +710,7 @@ class Unpickler:
k = self.marker() k = self.marker()
klass = stack[k + 1] klass = stack[k + 1]
del stack[k + 1] del stack[k + 1]
args = tuple(stack[k + 1:]) args = tuple(stack[k + 1:])
del stack[k:] del stack[k:]
instantiated = 0 instantiated = 0
if (not args and type(klass) is ClassType and if (not args and type(klass) is ClassType and
...@@ -726,7 +726,7 @@ class Unpickler: ...@@ -726,7 +726,7 @@ class Unpickler:
if not instantiated: if not instantiated:
value = apply(klass, args) value = apply(klass, args)
self.append(value) self.append(value)
dispatch[OBJ] = load_obj dispatch[OBJ] = load_obj
def load_global(self): def load_global(self):
module = self.readline()[:-1] module = self.readline()[:-1]
...@@ -761,8 +761,8 @@ class Unpickler: ...@@ -761,8 +761,8 @@ class Unpickler:
safe = None safe = None
if (not safe): if (not safe):
raise UnpicklingError, "%s is not safe for " \ raise UnpicklingError, "%s is not safe for " \
"unpickling" % callable "unpickling" % callable
if arg_tup is None: if arg_tup is None:
value = callable.__basicnew__() value = callable.__basicnew__()
...@@ -829,7 +829,7 @@ class Unpickler: ...@@ -829,7 +829,7 @@ class Unpickler:
del stack[mark:] del stack[mark:]
dispatch[APPENDS] = load_appends dispatch[APPENDS] = load_appends
def load_setitem(self): def load_setitem(self):
stack = self.stack stack = self.stack
value = stack[-1] value = stack[-1]
......
This diff is collapsed.
This diff is collapsed.
...@@ -129,7 +129,7 @@ class _posixfile_: ...@@ -129,7 +129,7 @@ class _posixfile_:
l_flags = fcntl.fcntl(file.fileno(), FCNTL.F_SETFL, l_flags) l_flags = fcntl.fcntl(file.fileno(), FCNTL.F_SETFL, l_flags)
if 'c' in which: if 'c' in which:
arg = ('!' not in which) # 0 is don't, 1 is do close on exec arg = ('!' not in which) # 0 is don't, 1 is do close on exec
l_flags = fcntl.fcntl(file.fileno(), FCNTL.F_SETFD, arg) l_flags = fcntl.fcntl(file.fileno(), FCNTL.F_SETFD, arg)
...@@ -142,7 +142,7 @@ class _posixfile_: ...@@ -142,7 +142,7 @@ class _posixfile_:
if FCNTL.O_NDELAY & l_flags: which = which + 'n' if FCNTL.O_NDELAY & l_flags: which = which + 'n'
if FCNTL.O_SYNC & l_flags: which = which + 's' if FCNTL.O_SYNC & l_flags: which = which + 's'
return which return which
def lock(self, how, *args): def lock(self, how, *args):
import struct, fcntl, FCNTL import struct, fcntl, FCNTL
...@@ -176,7 +176,7 @@ class _posixfile_: ...@@ -176,7 +176,7 @@ class _posixfile_:
'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5', 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
'bsdos2', 'bsdos3', 'bsdos4'): 'bsdos2', 'bsdos3', 'bsdos4'):
flock = struct.pack('lxxxxlxxxxlhh', \ flock = struct.pack('lxxxxlxxxxlhh', \
l_start, l_len, os.getpid(), l_type, l_whence) l_start, l_len, os.getpid(), l_type, l_whence)
elif sys.platform in ['aix3', 'aix4']: elif sys.platform in ['aix3', 'aix4']:
flock = struct.pack('hhlllii', \ flock = struct.pack('hhlllii', \
l_type, l_whence, l_start, l_len, 0, 0, 0) l_type, l_whence, l_start, l_len, 0, 0, 0)
......
...@@ -55,7 +55,7 @@ def join(a, *p): ...@@ -55,7 +55,7 @@ def join(a, *p):
# Trailing '/'es are stripped from head unless it is the root. # Trailing '/'es are stripped from head unless it is the root.
def split(p): def split(p):
"""Split a pathname. Returns tuple "(head, tail)" where "tail" is """Split a pathname. Returns tuple "(head, tail)" where "tail" is
everything after the final slash. Either part may be empty.""" everything after the final slash. Either part may be empty."""
i = p.rfind('/') + 1 i = p.rfind('/') + 1
head, tail = p[:i], p[i:] head, tail = p[:i], p[i:]
...@@ -93,7 +93,7 @@ def splitext(p): ...@@ -93,7 +93,7 @@ def splitext(p):
# path. Useful on DOS/Windows/NT; on Unix, the drive is always empty. # path. Useful on DOS/Windows/NT; on Unix, the drive is always empty.
def splitdrive(p): def splitdrive(p):
"""Split a pathname into drive and path. On Posix, drive is always """Split a pathname into drive and path. On Posix, drive is always
empty.""" empty."""
return '', p return '', p
...@@ -220,7 +220,7 @@ def sameopenfile(fp1, fp2): ...@@ -220,7 +220,7 @@ def sameopenfile(fp1, fp2):
def samestat(s1, s2): def samestat(s1, s2):
"""Test whether two stat buffers reference the same file""" """Test whether two stat buffers reference the same file"""
return s1[stat.ST_INO] == s2[stat.ST_INO] and \ return s1[stat.ST_INO] == s2[stat.ST_INO] and \
s1[stat.ST_DEV] == s2[stat.ST_DEV] s1[stat.ST_DEV] == s2[stat.ST_DEV]
# Is a path a mount point? # Is a path a mount point?
...@@ -253,7 +253,7 @@ def ismount(path): ...@@ -253,7 +253,7 @@ def ismount(path):
# or to impose a different order of visiting. # or to impose a different order of visiting.
def walk(top, func, arg): def walk(top, func, arg):
"""walk(top,func,arg) calls func(arg, d, files) for each directory "d" """walk(top,func,arg) calls func(arg, d, files) for each directory "d"
in the tree rooted at "top" (including "top" itself). "files" is a list in the tree rooted at "top" (including "top" itself). "files" is a list
of all the files and subdirs in directory "d". of all the files and subdirs in directory "d".
""" """
...@@ -263,10 +263,10 @@ def walk(top, func, arg): ...@@ -263,10 +263,10 @@ def walk(top, func, arg):
return return
func(arg, top, names) func(arg, top, names)
for name in names: for name in names:
name = join(top, name) name = join(top, name)
st = os.lstat(name) st = os.lstat(name)
if stat.S_ISDIR(st[stat.ST_MODE]): if stat.S_ISDIR(st[stat.ST_MODE]):
walk(name, func, arg) walk(name, func, arg)
# Expand paths beginning with '~' or '~user'. # Expand paths beginning with '~' or '~user'.
...@@ -279,7 +279,7 @@ def walk(top, func, arg): ...@@ -279,7 +279,7 @@ def walk(top, func, arg):
# variable expansion.) # variable expansion.)
def expanduser(path): def expanduser(path):
"""Expand ~ and ~user constructions. If user or $HOME is unknown, """Expand ~ and ~user constructions. If user or $HOME is unknown,
do nothing.""" do nothing."""
if path[:1] != '~': if path[:1] != '~':
return path return path
...@@ -349,7 +349,7 @@ def normpath(path): ...@@ -349,7 +349,7 @@ def normpath(path):
for comp in comps: for comp in comps:
if comp in ('', '.'): if comp in ('', '.'):
continue continue
if (comp != '..' or (not initial_slash and not new_comps) or if (comp != '..' or (not initial_slash and not new_comps) or
(new_comps and new_comps[-1] == '..')): (new_comps and new_comps[-1] == '..')):
new_comps.append(comp) new_comps.append(comp)
elif new_comps: elif new_comps:
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
"""Pseudo terminal utilities.""" """Pseudo terminal utilities."""
# Bugs: No signal handling. Doesn't set slave termios and window size. # Bugs: No signal handling. Doesn't set slave termios and window size.
# Only tested on Linux. # Only tested on Linux.
# See: W. Richard Stevens. 1992. Advanced Programming in the # See: W. Richard Stevens. 1992. Advanced Programming in the
# UNIX Environment. Chapter 19. # UNIX Environment. Chapter 19.
# Author: Steen Lumholt -- with additions by Guido. # Author: Steen Lumholt -- with additions by Guido.
from select import select from select import select
...@@ -17,133 +17,133 @@ STDERR_FILENO = 2 ...@@ -17,133 +17,133 @@ STDERR_FILENO = 2
CHILD = 0 CHILD = 0
def openpty(): def openpty():
"""openpty() -> (master_fd, slave_fd) """openpty() -> (master_fd, slave_fd)
Open a pty master/slave pair, using os.openpty() if possible.""" Open a pty master/slave pair, using os.openpty() if possible."""
try: try:
return os.openpty() return os.openpty()
except (AttributeError, OSError): except (AttributeError, OSError):
pass pass
master_fd, slave_name = _open_terminal() master_fd, slave_name = _open_terminal()
slave_fd = slave_open(slave_name) slave_fd = slave_open(slave_name)
return master_fd, slave_fd return master_fd, slave_fd
def master_open(): def master_open():
"""master_open() -> (master_fd, slave_name) """master_open() -> (master_fd, slave_name)
Open a pty master and return the fd, and the filename of the slave end. Open a pty master and return the fd, and the filename of the slave end.
Deprecated, use openpty() instead.""" Deprecated, use openpty() instead."""
try: try:
master_fd, slave_fd = os.openpty() master_fd, slave_fd = os.openpty()
except (AttributeError, OSError): except (AttributeError, OSError):
pass pass
else: else:
slave_name = os.ttyname(slave_fd) slave_name = os.ttyname(slave_fd)
os.close(slave_fd) os.close(slave_fd)
return master_fd, slave_name return master_fd, slave_name
return _open_terminal() return _open_terminal()
def _open_terminal(): def _open_terminal():
"""Open pty master and return (master_fd, tty_name). """Open pty master and return (master_fd, tty_name).
SGI and generic BSD version, for when openpty() fails.""" SGI and generic BSD version, for when openpty() fails."""
try: try:
import sgi import sgi
except ImportError: except ImportError:
pass pass
else: else:
try: try:
tty_name, master_fd = sgi._getpty(FCNTL.O_RDWR, 0666, 0) tty_name, master_fd = sgi._getpty(FCNTL.O_RDWR, 0666, 0)
except IOError, msg: except IOError, msg:
raise os.error, msg raise os.error, msg
return master_fd, tty_name return master_fd, tty_name
for x in 'pqrstuvwxyzPQRST': for x in 'pqrstuvwxyzPQRST':
for y in '0123456789abcdef': for y in '0123456789abcdef':
pty_name = '/dev/pty' + x + y pty_name = '/dev/pty' + x + y
try: try:
fd = os.open(pty_name, FCNTL.O_RDWR) fd = os.open(pty_name, FCNTL.O_RDWR)
except os.error: except os.error:
continue continue
return (fd, '/dev/tty' + x + y) return (fd, '/dev/tty' + x + y)
raise os.error, 'out of pty devices' raise os.error, 'out of pty devices'
def slave_open(tty_name): def slave_open(tty_name):
"""slave_open(tty_name) -> slave_fd """slave_open(tty_name) -> slave_fd
Open the pty slave and acquire the controlling terminal, returning Open the pty slave and acquire the controlling terminal, returning
opened filedescriptor. opened filedescriptor.
Deprecated, use openpty() instead.""" Deprecated, use openpty() instead."""
return os.open(tty_name, FCNTL.O_RDWR) return os.open(tty_name, FCNTL.O_RDWR)
def fork(): def fork():
"""fork() -> (pid, master_fd) """fork() -> (pid, master_fd)
Fork and make the child a session leader with a controlling terminal.""" Fork and make the child a session leader with a controlling terminal."""
try: try:
pid, fd = os.forkpty() pid, fd = os.forkpty()
except (AttributeError, OSError): except (AttributeError, OSError):
pass pass
else: else:
if pid == CHILD: if pid == CHILD:
try: try:
os.setsid() os.setsid()
except OSError: except OSError:
# os.forkpty() already set us session leader # os.forkpty() already set us session leader
pass pass
return pid, fd return pid, fd
master_fd, slave_fd = openpty() master_fd, slave_fd = openpty()
pid = os.fork() pid = os.fork()
if pid == CHILD: if pid == CHILD:
# Establish a new session. # Establish a new session.
os.setsid() os.setsid()
os.close(master_fd) os.close(master_fd)
# Slave becomes stdin/stdout/stderr of child. # Slave becomes stdin/stdout/stderr of child.
os.dup2(slave_fd, STDIN_FILENO) os.dup2(slave_fd, STDIN_FILENO)
os.dup2(slave_fd, STDOUT_FILENO) os.dup2(slave_fd, STDOUT_FILENO)
os.dup2(slave_fd, STDERR_FILENO) os.dup2(slave_fd, STDERR_FILENO)
if (slave_fd > STDERR_FILENO): if (slave_fd > STDERR_FILENO):
os.close (slave_fd) os.close (slave_fd)
# Parent and child process. # Parent and child process.
return pid, master_fd return pid, master_fd
def _writen(fd, data): def _writen(fd, data):
"""Write all the data to a descriptor.""" """Write all the data to a descriptor."""
while data != '': while data != '':
n = os.write(fd, data) n = os.write(fd, data)
data = data[n:] data = data[n:]
def _read(fd): def _read(fd):
"""Default read function.""" """Default read function."""
return os.read(fd, 1024) return os.read(fd, 1024)
def _copy(master_fd, master_read=_read, stdin_read=_read): def _copy(master_fd, master_read=_read, stdin_read=_read):
"""Parent copy loop. """Parent copy loop.
Copies Copies
pty master -> standard output (master_read) pty master -> standard output (master_read)
standard input -> pty master (stdin_read)""" standard input -> pty master (stdin_read)"""
while 1: while 1:
rfds, wfds, xfds = select( rfds, wfds, xfds = select(
[master_fd, STDIN_FILENO], [], []) [master_fd, STDIN_FILENO], [], [])
if master_fd in rfds: if master_fd in rfds:
data = master_read(master_fd) data = master_read(master_fd)
os.write(STDOUT_FILENO, data) os.write(STDOUT_FILENO, data)
if STDIN_FILENO in rfds: if STDIN_FILENO in rfds:
data = stdin_read(STDIN_FILENO) data = stdin_read(STDIN_FILENO)
_writen(master_fd, data) _writen(master_fd, data)
def spawn(argv, master_read=_read, stdin_read=_read): def spawn(argv, master_read=_read, stdin_read=_read):
"""Create a spawned process.""" """Create a spawned process."""
if type(argv) == type(''): if type(argv) == type(''):
argv = (argv,) argv = (argv,)
pid, master_fd = fork() pid, master_fd = fork()
if pid == CHILD: if pid == CHILD:
apply(os.execlp, (argv[0],) + argv) apply(os.execlp, (argv[0],) + argv)
mode = tty.tcgetattr(STDIN_FILENO) mode = tty.tcgetattr(STDIN_FILENO)
tty.setraw(STDIN_FILENO) tty.setraw(STDIN_FILENO)
try: try:
_copy(master_fd, master_read, stdin_read) _copy(master_fd, master_read, stdin_read)
except: except:
tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode) tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode)
This diff is collapsed.
...@@ -26,7 +26,7 @@ def encode(input, output, quotetabs): ...@@ -26,7 +26,7 @@ def encode(input, output, quotetabs):
'input' and 'output' are files with readline() and write() methods. 'input' and 'output' are files with readline() and write() methods.
The 'quotetabs' flag indicates whether tabs should be quoted. The 'quotetabs' flag indicates whether tabs should be quoted.
""" """
while 1: while 1:
line = input.readline() line = input.readline()
if not line: if not line:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment