Sending C-c to Emacs

lorinh at gmail.com lorinh at gmail.com
Mon Apr 3 21:36:40 EDT 2006


Hi all,

I've written a Python script with functionality similar to the Unix
"script" program, which keeps a record of shell commands issued (I
capture some additional stuff like timestamps). The code is borrowed
largely from
http://groups.google.com/group/comp.lang.python/msg/de40b36c6f0c53cc

Anyways, one problem is that it doesn't handle Control-C correctly.
This is a particular problem when invoking Emacs since C-x C-c is the
sequence to exit Emacs. Catching the KeyboardInterrupt and doing
os.kill(pid,signal.SIGINT) doesn't seem to do the trick.

A simplified version of the  program looks something like this (I've
eliminated the parts where I log the data to a file and some
tty-related cleanup stuff, this is just shuffling  data between user
and shell)

import select,os,pty
shell = '/bin/bash'
pid, fd = pty.fork()
if pid == 0:
 os.execvp(shell,(shell,))

# various tty magic goes here

exit = 0
while True:
 r, w, e = select.select([0, fd], [], [], 1)
 for File in  r:
  if File == 0:
   from_user = os.read(0, bufsize)
   os.write(fd, from_user)
  elif File==fd:
   try:
    from_shell = os.read(fd, bufsize)
    os.write(1, from_shell)
    if from_shell=='':
     exit=1
   except OSError:
    exit=1
 if exit==1:
   break


The problem is that this doesn't work when the user hits Control-C. I
thought the solution would be to send the child process a SIGINT, and I
tried to do that as follows:

try:
 r, w, e = select.select([0, fd], [], [], 1)
 ...
except KeyboardInterrupt:
 os.kill(pid,signal.SIGINT)


But that doesn't have the desired effect. When I have this code here,
it's as if I never hit Control-C at all. What's the proper way to pass
the Control-C to the child process?  

Thanks,

Lorin Hochstein




More information about the Python-list mailing list