X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=fishdescriptor%2Fpy%2Ffishdescriptor%2Ffish.py;h=763684bd4db460414dfcffbf91a4a2537c814d7f;hb=4f14a54c421cdc7799582c76d0f34eee7a86f3e7;hp=9c7fca839e44ae5c3c923952ee5019be1617d2f2;hpb=d8d60f17dad9d2e9a01729d9f21b0a99f1aeb4ce;p=chiark-utils.git diff --git a/fishdescriptor/py/fishdescriptor/fish.py b/fishdescriptor/py/fishdescriptor/fish.py index 9c7fca8..763684b 100644 --- a/fishdescriptor/py/fishdescriptor/fish.py +++ b/fishdescriptor/py/fishdescriptor/fish.py @@ -4,6 +4,7 @@ import socket import subprocess import os import pwd +import struct def _shuffle_fd3(): os.dup2(1,3) @@ -24,11 +25,11 @@ class Donor(): ) def _eval_integer(d, expr): - l = d._sp.stdin.readline() - if l != '!\n': raise RuntimeError("indonor said %s" % repr(l)) - d._sp.stdout.write(expr + '\n') - d._sp.stdout.flush() - l = d._sp.stdin.readline().rstrip('\n') + l = d._sp.stdout.readline() + if l != b'!\n': raise RuntimeError("indonor said %s" % repr(l)) + d._sp.stdin.write(expr.encode('utf-8') + b'\n') + d._sp.stdin.flush() + l = d._sp.stdout.readline().rstrip(b'\n') return int(l) def _eval_success(d, expr): @@ -50,14 +51,14 @@ class Donor(): ap = subprocess.Popen( stdin = subprocess.DEVNULL, stdout = subprocess.PIPE, - args = ['perl','-we',perl_script] + fds + 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(',')) @@ -76,11 +77,11 @@ class Donor(): def _sock_dir(d, target_euid): run_dir = '/run/user/%d' % target_euid if d._exists(run_dir): - return run_dir + 'fishdescriptor' + return run_dir + '/fishdescriptor' try: pw = pwd.getpwuid(target_euid) - return pw.pw_dir + '.fishdescriptor' + return pw.pw_dir + '/.fishdescriptor' except KeyError: pass @@ -98,7 +99,7 @@ class Donor(): 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 = '' @@ -116,14 +117,16 @@ class Donor(): 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() @@ -131,3 +134,5 @@ class Donor(): try: os.remove(our_sockname) except FileNotFoundError: pass + + return list(got_fds)