import subprocess
import os
import pwd
+import struct
def _shuffle_fd3():
os.dup2(1,3)
class Donor():
def __init__(d, pid):
- d._pid = pid
+ d.pid = pid
d._sp = subprocess.Popen(
preexec_fn = _shuffle_fd3,
stdin = subprocess.PIPE,
args = ['perl','-we',perl_script] + [str(x) for x in fds]
)
(output, dummy) = ap.communicate()
- return output
+ return output.decode('utf-8')
def donate(d, path, fds):
ancil = d._ancilmsg(fds)
- d._eval_success('di.donate(%s, %s)'
+ d._eval_success('di.donate(%s, [ %s ])'
% (repr(path), ancil))
return len(ancil.split(','))
sockdir = d._sock_dir(euid)
d.mkdir(sockdir)
- sockname = '%s/%s,%d' % (sockdir, os.uname().nodename, d._pid)
+ sockname = '%s/%s,%d' % (sockdir, os.uname().nodename, d.pid)
- target_root = '/proc/%d/root' % d._pid
+ target_root = '/proc/%d/root' % d.pid
if not d._exists(target_root):
target_root = ''
s.listen(1)
ancil_len = d.donate(our_sockname, fds)
- s2 = s.accept()
+ (s2, dummy) = s.accept()
(msg, ancil, flags, sender) = s2.recvmsg(1, ancil_len)
- got_fds = [ ]
+ got_fds = None
+ unpack_fmt = '%di' % len(fds)
for clvl, ctype, cdata in ancil:
if clvl == socket.SOL_SOCKET and ctype == socket.SCM_RIGHTS:
- got_fds += cdata # need to trim any surplus, and unpack
+ assert(got_fds is None)
+ got_fds = struct.unpack_from(unpack_fmt, cdata)
finally:
if s is not None: s.close()
try: os.remove(our_sockname)
except FileNotFoundError: pass
+
+ return list(got_fds)
+
+ def detach(d):
+ d._sp.stdin.close()