Several incompatible changes to the experimental proxy API to make it simpler
[rox-lib/lack.git] / python / rox / suchild.py
blob60de4b0fc84ecdc5abffb9f586085ab775990a87
1 """This is the child program run by the su module. Do not import this module."""
2 import os, sys
3 import cPickle as pickle
4 import time
5 import shutil
7 import proxy
9 read_watches = []
10 write_watches = []
11 streams = {}
13 class Watch:
14 """Contains a file descriptor and a function to call when it's ready"""
15 def __init__(self, fd, fn):
16 self.fd = fd
17 self.ready = fn
19 def fileno(self):
20 return self.fd
22 class SuSlave(proxy.SlaveProxy):
23 """A simple implementation of SlaveProxy that doesn't use gtk"""
24 def __init__(self, to_parent, from_parent, slave):
25 self.read_watch = Watch(from_parent, self.read_ready)
26 self.write_watch = Watch(to_parent, self.write_ready)
27 proxy.SlaveProxy.__init__(self, to_parent, from_parent, slave)
29 def enable_read_watch(self):
30 assert self.read_watch not in read_watches
31 read_watches.append(self.read_watch)
33 def enable_write_watch(self):
34 assert self.write_watch not in write_watches
35 write_watches.append(self.write_watch)
37 class Slave:
38 """This object runs as another user. Most methods behave in a similar
39 way to the standard python methods of the same name."""
41 def spawnvpe(self, mode, file, args, env = None):
42 if env is None:
43 return os.spawnvp(mode, file, args)
44 else:
45 return os.spawnvpe(mode, file, args, env)
47 def waitpid(self, pid, flags):
48 return os.waitpid(pid, flags)
50 def getuid(self):
51 return os.getuid()
53 def setuid(self, uid):
54 return os.setuid(uid)
56 def rmtree(self, path):
57 return shutil.rmtree(path)
59 def unlink(self, path):
60 return os.unlink(path)
62 def open(self, path, mode = 'r'):
63 stream = file(path, mode)
64 streams[id(stream)] = stream
65 return id(stream)
67 def close(self, stream):
68 streams[stream].close()
69 del streams[stream]
71 def read(self, stream, length = 0):
72 return streams[stream].read(length)
74 def write(self, stream, data):
75 return streams[stream].write(data)
77 def rename(self, old, new):
78 return os.rename(old, new)
80 def chmod(self, path, mode):
81 return os.chmod(path, mode)
83 if __name__ == '__main__':
84 from select import select
86 to_parent, from_parent = map(int, sys.argv[1:])
88 sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))))
90 slave_proxy = SuSlave(to_parent, from_parent, Slave())
92 while read_watches or write_watches:
93 readable, writable = select(read_watches, write_watches, [])[:2]
94 for w in readable:
95 if not w.ready():
96 read_watches.remove(w)
97 for w in writable:
98 if not w.ready():
99 write_watches.remove(w)