This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[AW] RE: Brainstorming a fix for CTRL-C handling in an emacs shell buf fer (non-TTY)


I hesitate even to call this an answer really.  Just wanted to close
out this thread of discussion by reporting what I have discovered.

1. Bash does not SIGINT its children when it receives a SIGINT.  That
   appears to be by design, at least that's what the code appears to
   tell me.  I wrote a test program with handlers for SIGTERM and SIGINT
   and then tested with bash 2.04 and newer...  on cygwin, Linux, and
   FreeBSD.  Bash never signals its children when it receives a SIGINT
   or SIGTERM (kill -SIGTERM pid or kill -SIGINT pid).  This is true
   whether bash is running in a pipe or not.
2. Bash does not turn over control of the tty to a child process if
   bash thinks it's running in a pipe.  This is also by design (in jobs.c).
   This is why I always see t->getpgid != myself->pgid when running
   commands from a bash prompt inside an FSF Emacs shell buffer.
3. My 2nd (or was it 3rd) patch seems to do the best job of handling
   the CTRL-C "for me", except I also needed to account for the sid
   so I don't kill the programs on other sids on the same ctty.
4. FSF NT Emacs users should not set "tty" in their CYGWIN environment
   variable if they plan to run bash in an Emacs buffer.
5. Cygwin XEmacs 21.1.13 and 21.4.0 binaries provided by Andy Piper on
   the XEmacs ftp site do interact properly with cygwin/bash in a shell
   buffer, as promised.  But this is not an alternative for me for
   reasons I mentioned earlier (problems with JDE, ECB, etc).

Christopher, thanks very much for your help troubleshooting this.  Sorry
I've not come up with a better solution, this is not an easy problem to
troubleshoot as I found out.  That's probably why nobody's fixed it yet
I suppose.  Regretably, I've probably not gotten much closer to a
general-purpose solution.  I know what doesn't work though ;->

As a contribution, here is the final patch that makes CTRL-C handling work
best "for me" in an FSF Emacs shell buffer.  Patch was generated against
the latest exceptions.cc in winsup cvs as of this morning (5/15/2001).

I don't expect you to put the ctrl_c_handler patch into the sources for
reasons you've already mentioned (fixing the symptom, not the root
problem).  I've decided I can just download the 1.3.2 sources when they
get released, patch it and compile that DLL for my own personal use.
I understand of course that it will be unsupported and non-standard,
so I won't bug the list if I run into problems.

If someone else can make use of it, so much the better.  But I've come
to the end of available alternatives that I can think of at the moment.
Suggestions for further exploration are welcome, however "free time"
to troubleshoot further has suddenly become quite scarce for me.


Index: src/winsup/cygwin/exceptions.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/exceptions.cc,v
retrieving revision 1.84
diff --unified=3 -r1.84 exceptions.cc
--- exceptions.cc	2001/05/08 15:16:48	1.84
+++ exceptions.cc	2001/05/15 14:13:51
@@ -22,6 +22,8 @@
 #include "perprocess.h"
 #include "security.h"
 
+#include <unistd.h>
+
 #define CALL_HANDLER_RETRY 20
 
 char debugger_command[2 * MAX_PATH + 20];
@@ -904,9 +906,22 @@
   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 () && pid_exists (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 not set "tty" in their CYGWIN environment
+       variable if they plan to run bash in an Emacs buffer.
+       */
+  if (t->getpgid() && pid_exists (t->getpgid ()) &&
+      ((!isatty(0) && (myself->pid != myself->pgid ||
+                       t->getsid() != myself->sid)) ||
+       (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

-----Original Message-----
From: Christopher Faylor [mailto:cgf@redhat.com]
Sent: Tuesday, May 08, 2001 5:59 PM
To: 'cygwin@cygwin.com'
Subject: Re: Brainstorming a fix for CTRL-C handling in an emacs shell
buf fer (non-TTY)


On Tue, May 08, 2001 at 05:46:05PM -0600, Troy Noble wrote:
>Looks like a I caught a break this time.
>
>I can't tell if we're converging on a solution at this point or
>diverging.  However, I did want to get you some usable strace
>output if possible.

This is a symptom of things working, though.  I'm trying to get an
strace of a failing situation.

>Let me know if I've worn out my welcome or if you want me to
>move to the developer list to cut down the traffic on this list.
>
>I started bash in an emacs buffer, then ran "strace bash",
>then ran my "ls -lR".  Then pressed CTRL-C.
>
>If I read the strace output correctly,
>it looks like bash figures out that it has a child process,
>and I can see the child process responding to the SIGINT signal.

I don't see bash sending a SIGINT.

>The "ls" process ctrl_c_handler never gets invoked, which is
>good.  So I'm 99% sure that ls shut down in response to bash's
>signal.  Bash then detects that the child exited and removes
>it from its table of child processes.

It does receive a SIGINT and die but I don't know why.  Are you
working with a pure Cygwin from CVS?

cgf

--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]