I spent some time debugging M-x shell in XEmacs on 32-bit Cygwin.
Here's what I found out.
In the child after fork() but before exec(), the setsid() call in
disconnect_controlling_terminal() is causing the subprocess not to
function after it gets spawned.
Here is a patch which works around the problem, enabling M-x shell to
work for bash and zsh (at least):
diff -r 00f2705e2cb3 src/sysdep.c
--- a/src/sysdep.c Mon Jan 26 08:53:07 2015 -0500
+++ b/src/sysdep.c Tue Jan 27 22:15:16 2015 -0500
@@ -1319,7 +1319,7 @@
void
disconnect_controlling_terminal (void)
{
-# ifdef HAVE_SETSID
+# if defined(HAVE_SETSID) && !defined(CYGWIN)
/* Controlling terminals are attached to a session.
Create a new session for us; it will have no controlling
terminal. This also, of course, puts us in our own
HOWEVER - I don't understand why this should be necessary.
I here reproduce all of disconnect_controlling_terminal() for your
reading pleasure.
void
disconnect_controlling_terminal (void)
{
# if defined(HAVE_SETSID) && !defined(CYGWIN)
/* Controlling terminals are attached to a session.
Create a new session for us; it will have no controlling
terminal. This also, of course, puts us in our own
process group. */
setsid ();
# else
/* Put us in our own process group. */
EMACS_SEPARATE_PROCESS_GROUP ();
# if defined (TIOCNOTTY)
/* This is the older way of disconnecting the controlling
terminal, on 4.3 BSD. We must open /dev/tty; using
filedesc 0 is not sufficient because it could be
something else (e.g. our stdin was redirected to
another terminal).
*/
{
int j = open ("/dev/tty", O_RDWR, 0);
ioctl (j, TIOCNOTTY, 0);
close (j);
}
# endif /* TIOCNOTTY */
/*
On systems without TIOCNOTTY and without
setsid(), we don't need to do anything more to
disconnect our controlling terminal. Here is
what the man page for termio(7) from a SYSV 3.2
system says:
"The first terminal file opened by the process group leader
of a terminal file not already associated with a process
group becomes the control terminal for that process group.
The control terminal plays a special role in handling quit
and interrupt signals, as discussed below. The control
terminal is inherited by a child process during a fork(2).
A process can break this association by changing its process
group using setpgrp(2)."
*/
# endif /* not HAVE_SETSID */
}
Since Cygwin doesn't seem to have TIOCNOTTY, commenting out the
setsid() call reduces disconnect_controlling_terminal to:
void
disconnect_controlling_terminal (void)
{
# 1330 "sysdep.c"
setpgid (0, 0);
# 1362 "sysdep.c"
}
Incidentally, that setpgid() call causes bash to complain at startup:
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
Thanks for any insight you can offer.
- Vin
_______________________________________________
XEmacs-Beta mailing list
XEmacs-Beta(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-beta