X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=fishdescriptor%2Ffishdescriptor;h=d583533c210faf64d351f1536af350fceafe887c;hb=086feb1679c895d85c9f0f533c5cf0806a52a6dc;hp=34d91e6687691e0f498077c9a3a143a2320f2bcc;hpb=7e2d804d6ca8b9f9f09ba67f3d963b526e8b6d37;p=chiark-utils.git diff --git a/fishdescriptor/fishdescriptor b/fishdescriptor/fishdescriptor index 34d91e6..d583533 100755 --- a/fishdescriptor/fishdescriptor +++ b/fishdescriptor/fishdescriptor @@ -1,16 +1,38 @@ #!/usr/bin/python3 +# This file is part of chiark-utils, a collection of useful programs +# used on chiark.greenend.org.uk. +# +# This file is: +# Copyright 2018 Citrix Systems Ltd +# +# This is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3, or (at your option) any later version. +# +# This is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, consult the Free Software Foundation's +# website at www.fsf.org, or the GNU Project website at www.gnu.org. + import sys import fishdescriptor.fish import optparse import re +import subprocess +import socket +import os donor = None usage = '''fishdescriptor [-p|--pid] ... [-p|--pid ...] s - [=] + [=] fish the openfile referenced by descriptor in (the most recent) and keep a descriptor onto it; and, optionally, give it the number for exec @@ -32,14 +54,17 @@ fdmap = { } # fdmap[nominal] = (actual, Donor, there) def implement_pending(): - actuals = donor.fish([pend[1] for pend in pending]) + try: actuals = donor.fish([pend[1] for pend in pending]) + except fishdescriptor.fish.Error as e: + print('fishdescriptor error: %s' % e, file=sys.stderr) + sys.exit(127) assert(len(actuals) == len(pending)) for (nominal, there), actual in zip(pending, actuals): overwriting_info = fdmap.get(nominal) if overwriting_info is not None: os.close(overwriting_info[0]) - fdmap[nominal] = (actual, Donor, there) + fdmap[nominal] = [actual, donor, there] -def implmement_sockinfo(nominal): +def implement_sockinfo(nominal): (actual, tdonor, there) = fdmap[nominal] # socket.fromfd requires the AF. But of course we don't know the AF. # There isn't a sane way to get it in Python: @@ -66,7 +91,7 @@ def implmement_sockinfo(nominal): (output, dummy) = famp.communicate() family = int(output) - sock = socket.fromfd(fd, family, 0) + sock = socket.fromfd(actual, family, 0) print("[%s] %d sockinfo" % (tdonor.pid, there), end='') for f in (lambda: socket.AddressFamily(family).name, @@ -80,7 +105,7 @@ def implmement_sockinfo(nominal): sock.close() def permute_fds_for_exec(): - actual2intended = { info[0]: nominal for nominal, info in fdmap.items } + actual2intended = { info[0]: nominal for nominal, info in fdmap.items() } # invariant at the start of each loop iteration: # for each intended (aka `nominal') we have processed: # relevant open-file is only held in fd intended @@ -101,20 +126,20 @@ def permute_fds_for_exec(): if inway_intended is not None: inway_moved = os.dup(intended) actual2intended[inway_moved] = inway_intended - fdmap[inway_intented][0] = inway_moved + fdmap[inway_intended][0] = inway_moved os.dup2(actual, intended) os.close(actual) def implement_exec(argl): if donor is not None: donor.detach() sys.stdout.flush() - permut_fds_for_exec() + permute_fds_for_exec() os.execvp(argl[0], argl) def set_donor(pid): global donor if donor is not None: donor.detach() - donor = fishdescriptor.fish.Donor(pid) + donor = fishdescriptor.fish.Donor(pid, debug=ov.debug) def ocb_set_donor(option, opt, value, parser): set_donor(value) @@ -136,6 +161,9 @@ def process_args(): op.disable_interspersed_args() op.add_option('-p','--pid', type='int', action='callback', callback=ocb_set_donor) + op.add_option('-D','--debug', action='store_const', + dest='debug', const=sys.stderr) + ov.debug = None args = sys.argv[1:] last_nominal = None # None or (nominal,) ie None or (None,) or (int,) @@ -145,10 +173,8 @@ def process_args(): if not len(args): break arg = args.pop(0) - print("ARG %s" % arg, file=sys.stderr) if donor is None: - print("SET_DONOR", file=sys.stderr) set_donor(int(arg)) elif arg_matches(r'^(?:(\d+)=)?(\d+)?$'): (nominal, there) = m.groups()