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