Mail Archives: cygwin/2010/10/19/09:32:49
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.
Ken
--
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
- Raw text -