From: slantin@eis.calstate.edu (Sam Lantinga)
Newsgroups: comp.unix.wizards
Subject: SIGINT from keyboard to selected process (or other solution)
Date: 16 Oct 92 02:06:57 GMT
Organization: Calif State Univ/Electronic Information Services


  I am working on a program called 'shawing', and have run into a 
serious bug.  The basic program structure is:

1. a pty is set up, and a shell is forked and exec'ed with the pty as
   its stdin, stdout, and stderr.
2. the parent process forks a process that reads from the terminal, and
   writes to the pty, casing each line for an escape sequence.
3. the parent process continues by reading from the pty and writing
   to the terminal.

  My problem is that when I execute the subshell and send an interrupt,
    the interrupt disrupts the read process, and everything goes bananas.
    I made a script of it:


    

Script started on Sat Oct 10 20:59:57 1992

/* I telnet into the system and look at my prompt. */
$ PS1="Hmm? "
Hmm? shawing -v   /* I start the program */
Escape character is '+'.
Current shell is /bin/ksh
Current log is /cosy/u/s/slantin/iolog29552
Hmm? PS1="pty: "    /* I change the prompt for tracing of what shell is where */
pty: +subsh   /* I execute the subshell escape.  At this point, the pty read
                 process is still active; I haven't specified that it be 
                 blocked.  SIGINT and SIGQUIT are caught by both the pty
                 read process and the terminal read process.  the "pty: "
                 shell is under complete control of the pty, so it won't 
                 recieve signals from the real terminal.  */
Hmm? ^C    I sent a SIGINT.  The signals are caught, and the pty read
             used to fail with EINTR until I caught the fail.  I figure
             that catching the failure would prevent the problem, but I
             guess not.  For full effect, take this following portion and
             cat it to your screen. *grin* */
pty: |
@^B^CT

Hmm? 

^A@^B^D^T-^-^-^-^


telnet> z   /* My terminal froze at the remote end. */

Stopped
% 
script done on Sat Oct 10 21:04:45 1992

/*  The only process that stops is the pty read process.  The others
    just hang around until I kill them.  I tried it with the block option,
    and it sortof worked.  It didn't freeze my terminal, but it did 
    try, and then exited.  I even made sure that it wouldn't be able to
    write anything to my screen by doing 'who' in the pty shell, and 
    watched as "wh" echoed and then it blocked.  (I do the blocking
    by having the read process check a flag every read, and pause()'ing
    if it shows that it needs to block.) */

So. :)  I have a question worthy of a real guru. :)
   "How do I enable SIGINT on the subshell, and disable it for the 
    shawing processes?  Or, how can I prevent the read from going 
    bananas?"

I have a few answers, but they are messy:
  1:  Find a different way to block the read process that doesn't
      use pause(), and mandatorily block pty output at any subshell.
  2:  the subshell under a separate pty.   *really messy*
  3:  Disable signals on the subshell.

There is another way....
  4:  Find out why read() goes bananas on a signales ba and fix that. :)


Any comments? :)
         -Sam.

Please email me at slantin@swrl36.calstate.edu
Newsgroups: comp.unix.wizards