Signal Catch & Ignore

I am trying to write a program that will run a program on a remote machine using ssh and transmit its SIGINT signals without killing my ssh connection. If I worked on the terminal, it would be easy with something like

ssh -t -t host "command to run"

I tried this with the following script:

#!/bin/bash

ssh -t -t host "program $@"

and when I run it from the terminal, it works fine, but when proofgeneral runs this script and sends it SIGINT, it just finishes killing the program (I think it cannot highlight the terminal?).

I have the following code mess:

CTRL_C = "<CTRL-C>"

def endpoint(proc, handler):
    signal.signal(2, signal.SIG_IGN)

    inp = ""
    out = ""
    err = ""

    inp_from_fd = sys.stdin.fileno()
    inp_to_fd   = proc.stdin.fileno()
    out_from_fd = proc.stdout.fileno()
    out_to_fd   = sys.stdout.fileno()
    err_from_fd = proc.stderr.fileno()
    err_to_fd   = sys.stderr.fileno()

    while True:
       try:
           ins,outs,_ = select.select([inp_from_fd, out_from_fd, err_from_fd],
                                      [inp_to_fd, out_to_fd, err_to_fd],
                                      [])
           for fd in ins:
               if fd == inp_from_fd:
                   k   = os.read(fd, 1024)
                   if k == "":
                       os.close(proc.stdin.fileno())
                       return
                   inp = inp + k
               elif fd == out_from_fd:
                   k   = os.read(fd, 1024)
                   out = out + k
               elif fd == err_from_fd:
                   k   = os.read(fd, 1024)
                   err = err + k
               else:
                   assert False
           for fd in outs:
               if fd == inp_to_fd:
                   while CTRL_C in inp:
                       proc.send_signal(2)
                       p = inp.find(CTRL_C)
                       inp = inp[0:p] + inp[p+len(CTRL_C):]
                   k = os.write(fd, inp)
                   inp = inp[k:]
               elif fd == out_to_fd:
                   k = os.write(fd, out)
                   out = out[k:]
               elif fd == err_to_fd:
                   k = os.write(fd, err)
                   err = err[k:]
               else:
                   assert False
       except select.error:
           pass
       except KeyboardInterrupt:
           handler()
       except IOError, e:
           pass

def usage(args):
    print "must specify --client or --server" 

if __name__ == '__main__':
    if len(sys.argv) == 1:
        usage(sys.argv)
    elif sys.argv[1] == '--server':
        proc = subprocess.Popen(sys.argv[2:],
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        def INT():
            proc.stdin.write(CTRL_C)
            proc.stdin.flush()
        endpoint(proc, INT)
    elif '--client' in sys.argv:
        proc = subprocess.Popen(sys.argv[2:],
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        import time
        time.sleep(1)
        def INT():
            pass
        endpoint(proc, INT)
    else:
        usage(sys.argv)

which I invoke using something like:

remote.py --client ssh -t -t host "remote.py --server <program-to-run> <args>"

-, ? 2 , ssh ( "Killed by signal 2.", ). python ? ? ?

.

+3
1

os.setpgrp( man- setpgrp),

+1

All Articles