Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com Message-ID: <8F23E55D511AD5119A6800D0B76FDDE11E100F@cpex3.channelpoint.com> From: Troy Noble To: "'cygwin AT cygwin DOT com'" Cc: "'andrewi AT gnu DOT org'" Subject: RE: Brainstorming a fix for CTRL-C handling in an emacs shell buf fer (non-TTY) Date: Sun, 6 May 2001 22:16:38 -0600 MIME-Version: 1.0 X-Mailer: Internet Mail Service (5.5.2653.19) Content-Type: text/plain; charset="iso-8859-1" X-Scanned-By: MIMEDefang 1.0 (http://www.roaringpenguin.com/mimedefang/) Christopher, Looks like t->getpgid() is OK, it's the t->getpgid () != myself->pid that's causing the behavior... and I think I understand why now. Thanks for leading me in the right direction. What do you think about the patch below for exceptions.cc instead? No extra environment variables required this time ;-> Note that I also determined that FSF Emacs users SHOULD NOT use CYGWIN=tty if they plan to run inside a shell buffer. Otherwise the CTRL-C handler doesn't get setup or invoked properly for reasons I probably don't need to elaborate on. This likely explains why some folks have reported not being able to kill other non-cygwin child processes (like java.exe for example) when running bash in a shell buffer. They probably had CYGWIN=tty set. You probably already knew that, I thought I'd just pass it along for others who might be having that same problem. --- exceptions.cc-orig Fri May 4 23:07:20 2001 +++ exceptions.cc Sun May 6 21:47:03 2001 @@ -11,6 +11,7 @@ #include "winsup.h" #include #include +#include #include "exceptions.h" #include "sync.h" @@ -904,8 +905,21 @@ tty_min *t = cygwin_shared->tty.get_tty (myself->ctty); /* Ignore this if we're not the process group lead since it should be handled *by* the process group leader. */ - if (t->getpgid () && (t->getpgid () != myself->pid || - (GetTickCount () - t->last_ctrl_c) < MIN_CTRL_C_SLOP)) + /* Note: t->getpgid() does not correctly reflect the pid of the process + group leader when stdin is a pipe (when isatty(0) == 0). + So when a native Win32 program like NT Emacs opens a pipe and supplies + that as stdin for a cygwin process, this handler should respond to the + CTRL-C when pid == pgid rather than when pid == t->getpgid(). + Inside a console window or cygwin-aware XEmacs or rxvt for example, + isatty(0) == 1 so the proper behavior is to kill the process whose + pid == t->getpgid(). + NT Emacs users should never set "tty" in their CYGWIN environment + variable if they plan to run bash in an Emacs buffer. + */ + if (t->getpgid() && + ((!isatty(0) && myself->pid != myself->pgid) || + (isatty(0) && (t->getpgid () != myself->pid)) || + ((GetTickCount () - t->last_ctrl_c) < MIN_CTRL_C_SLOP))) return TRUE; else /* Otherwise we just send a SIGINT to the process group and return TRUE (to indicate Just as Andrew Innes said in http://sources.redhat.com/ml/cygwin/2001-01/msg00928.html FSF Emacs 20.7.1 opens a pipe and passes the read end to the bash child process as its stdin. I read through the code just to see what it was doing so I could understand what was going on. Back on the cygwin side... In dtable::init_std_file_from_handle at line 202 I see: else if (GetFileType (handle) == FILE_TYPE_PIPE) Through a long sequence of steps, the end result is that the array of fds gets initialized in such a way that isatty(0) always returns 0. Therefore the code that switches the tty's PGID when a child forks never kicks in. I should add... I see this as a GOOD thing that you would not want to change, otherwise you'd never be able to kill the process leader for a set of commands in a pipe. So the simplest solution seems to be to change the ctrl_c_handler per the above patch. I too wrote a simple win32 program that emulated the behavior of NT Emacs's method of pipe/stdin handling. And was able to reproduce it quite easily. I can send the sources along if you'd like... so you wouldn't have to download/install FSF Emacs if you didn't want to ;-> An interesting way to reproduce all of this without running FSF Emacs or even writing a test program: 1. put the following code in the exceptions.cc:ctrl_c_handler printf("isatty(0)=%d t->getpgid()=%d myself->pid=%d pgid=%d ppid=%d progname=%s\n", isatty(0), t->getpgid(), myself->pid, myself->pgid, myself->ppid, myself->progname); 2. start up a bash shell in a console window. 3. create a file /tmp/tmp.sh that looks like: sleep 10 4. run bash getpgid()=608 myself->pid=112 pgid=608 ppid=608 progname=c:\cygwin\bin\sleep.exe isatty(0)=0 t->getpgid()=608 myself->pid=608 pgid=608 ppid=1468 progname=c:\cygwin\bin\bash.exe isatty(0)=0 t->getpgid()=608 myself->pid=1468 pgid=1468 ppid=1 progname=C:\cygwin\bin\bash.exe Notice that the child shell (pid=608) is the pgid... rather than the child sleep process (pid=112). Sorry for the long post. Hope this solves it once and for all. I'm still willing to pursue further if you don't think this is the right approach yet. Thanks again for your help, Troy -----Original Message----- From: Christopher Faylor [mailto:cgf AT redhat DOT com] Sent: Saturday, May 05, 2001 2:25 PM To: 'cygwin AT cygwin DOT com' Subject: Re: Brainstorming a fix for CTRL-C handling in an emacs shell buf fer (non-TTY) On Sat, May 05, 2001 at 02:19:24PM -0600, Troy Noble wrote: >So where would you recommend we go from here? > >Maybe looking into the TTY code, and figuring out why it doesn't >like the way Emacs is opening the pipe to stdin on cygwin processes? Look at the ctrl_c_handler code and tell me why the test for t->getpgid() being nonzero is inadequate. I actually wrote a program to test this and it works fine for me. I'm not going to download Xemacs, however. I've heard that it is unstable... cgf -- Want to unsubscribe from this list? Check out: http://cygwin.com/ml/#unsubscribe-simple -- Want to unsubscribe from this list? Check out: http://cygwin.com/ml/#unsubscribe-simple