Sending signals to a subprocess

Christopher Faylor cgf-use-the-mailinglist-please@cygwin.com
Tue Oct 19 15:47:00 GMT 2010


On Tue, Oct 19, 2010 at 09:32:34AM -0400, Ken Brown wrote:
>On 10/18/2010 4:18 PM, Christopher Faylor wrote:
>> On Mon, Oct 18, 2010 at 03:40:21PM -0400, Ken Brown wrote:
>>> On 10/18/2010 2:34 PM, Christopher Faylor wrote:
>>>> On Sat, Oct 16, 2010 at 02:06:56PM -0400, Ken Brown wrote:
>>>>> On 10/16/2010 1:17 PM, Ken Brown wrote:
>>>>>> I could use some help fixing a longstanding bug in the Cygwin build of
>>>>>> emacs, in which emacs is unable to send signals to subprocesses.  A
>>>>>> symptom from the user's point of view is that one cannot interrupt a
>>>>>> process in shell mode by typing C-c C-c.  I've found a workaround that
>>>>>> handles that case (SIGINT), as well as SIGQUIT and SIGTSTP.  But as long
>>>>>> as I'm fixing this, I'd like to do it right and figure out how to handle
>>>>>> all signals.
>>>>>>
>>>>>> This boils down to finding the right process group ID to pass to 'kill'.
>>>>>> On systems that have TIOCGPGRP, emacs uses the following code (in
>>>>>> src/process.c) to get this ID:
>>>>>>
>>>>>> /* Return the foreground process group for the tty/pty that
>>>>>>        the process P uses.  */
>>>>>> static int
>>>>>> emacs_get_tty_pgrp (p)
>>>>>>          struct Lisp_Process *p;
>>>>>> {
>>>>>>       int gid = -1;
>>>>>>
>>>>>> #ifdef TIOCGPGRP
>>>>>>       if (ioctl (p->infd, TIOCGPGRP,&gid) == -1&&    ! NILP (p->tty_name))
>>>>>>         {
>>>>>>           int fd;
>>>>>>           /* Some OS:es (Solaris 8/9) does not allow TIOCGPGRP from the
>>>>>> 	 master side.  Try the slave side.  */
>>>>>>           fd = emacs_open (SDATA (p->tty_name), O_RDONLY, 0);
>>>>>>
>>>>>>           if (fd != -1)
>>>>>> 	{
>>>>>> 	  ioctl (fd, TIOCGPGRP,&gid);
>>>>>> 	  emacs_close (fd);
>>>>>> 	}
>>>>>>         }
>>>>>> #endif /* defined (TIOCGPGRP ) */
>>>>>>
>>>>>>       return gid;
>>>>>> }
>>>>>>
>>>>>> What's the right way to do this in Cygwin?
>>>>>
>>>>> I guess it's clear from the context, but I should have said that the
>>>>> problem only arises when emacs has to communicate with the subprocess
>>>>> through a tty that is not the controlling tty of emacs.  So tcgetpgrp()
>>>>> doesn't work.
>>>>
>>>> I am a little confused as to the difference between tcgetpgrp and
>>>> TIOCGPGRP given this man page description from "man 4 tty_ioctl" on
>>>> linux:
>>>>
>>>>          TIOCGPGRP pid_t *argp
>>>>                 When successful, equivalent to *argp = tcgetpgrp(fd).
>>>>                 Get the process group ID of the foreground process group on this terminal.
>>>>
>>>>          TIOCSPGRP const pid_t *argp
>>>>                 Equivalent to tcsetpgrp(fd, *argp).
>>>>                 Set the foreground process group ID of this terminal.
>>>>
>>>> Do you have a simple test case which demonstrates the difference between
>>>> the calls?  It seems odd that TIOCGPGRP would allow more access to a tty
>>>> than tcgetpgrp.
>>>
>>> The difference is that, according to POSIX, tcgetpgrp is required to
>>> fail unless fd references the controlling terminal of the calling
>>> process.  Ironically, Cygwin's tcgetpgrp used to succeed in this
>>> situation until Corinna fixed it a year ago:
>>>
>>>    http://www.cygwin.com/ml/cygwin-patches/2009-q4/msg00045.html
>>
>> Yes, I got that but TIOCGPGRP seems to have that same limitation on
>> Linux.  That's why I quoted the above man page.  A simple test case
>> (tm) seems to bear out the fact that the two are the same.
>
>I just tried an experiment, and now I'm thoroughly confused.  I inserted 
>"#undef TIOCGPGRP" into process.c in the emacs source and rebuilt it on 
>Linux.  [Technical note if anyone wants to try to reproduce this: I also 
>inserted "#undef SIGNALS_VIA_CHARACTERS", since SIGNALS_VIA_CHARACTERS 
>provides an alternate method of sending signals to processes; this is in 
>fact my workaround on Cygwin.]  Then trying to kill a process running in 
>an emacs shell with C-c C-c fails the same way it fails in Cygwin.  So 
>somehow TIOCGPGRP is doing the right thing under Linux in the emacs code 
>above, in spite of its limitations.  I don't understand why.  When I get 
>a chance (not today), I'll try running emacs under gdb to see if I can 
>figure out what's going on.
>
>I guess this should mean that if you implement TIOCGPGRP in Cygwin and 
>make it emulate Linux, it should work for emacs in Cygwin too.  I can 
>also try to see if tcgetpgrp works instead of TIOCGPGRP.  I'm 
>embarrassed to say that I didn't actually try this before, because my 
>understanding of the documentation was that it wouldn't work.  You can 
>see I don't think like a programmer.

As I mentioned, my test case shows that when run on Linux, TIOCPGRP and
tcgetpgrp are the same.  So, given that, if I implemented TIOCPGRP it
wouldn't solve your problem.

How about if you modify the test case that I provided and show me what's
different?  Is this an issue with opening the wrong side of a pty, like
trying to run tcgetpgrp on the master rather than the slave or vice versa?

cgf

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple



More information about the Cygwin mailing list