[ Added Ben Wing, who knows the most about XEmacs event loop, to Cc. ]
Gunnar Evermann <ge204(a)eng.cam.ac.uk> writes:
Simon Josefsson <simon(a)josefsson.org> writes:
> $ xemacs -vanilla
> (open-network-stream "bug" nil "10.0.0.42" 42)
>
> Now XEmacs 21.1 (and 20.4) is hung, C-g doesn't do anything. XEmacs
> 21.2 seem fine. Perhaps the solution used there could be back-ported
> to XEmacs 21.1?
I am afraid there are two bugs here. The first one is fundamental and
causes C-g in X not to work for interrupting system calls and the
second one makes it work in 21.2 nevertheless. Alas I only understand
and can "fix" the latter :-(
Some explanations follow. (warning: I looked at most of this code for
the first time and don't understand some of it):
- before calling connect() we call slow_down_interrupts() (for rather
unclear reasons documented in the slightly strange comments).
- slow_down_interrupts ends up calling unrequest_sigio_on_device()
for the X file descriptor. In 21.2 this contains
------------
#if defined (I_SETSIG) && !defined(HPUX10)
{
int events=0;
ioctl (filedesc, I_GETSIG, &events);
ioctl (filedesc, I_SETSIG, events & ~S_INPUT);
}
#elif defined (FASYNC)
fcntl (filedesc, F_SETFL, fcntl (filedesc, F_GETFL, 0) & ~FASYNC);
-------------
On Linux with glibc2.1 I_SETSIG is defined but the ioctl don't
actually work (this seems to be a feature), strace shows:
14:36:07 ioctl(6, CDROMVOLCTRL, 0xbfffea84) = -1 EINVAL (Invalid argument)
<0.000010>
14:36:07 ioctl(6, CDROMEJECT, 0) = -1 EINVAL (Invalid argument) <0.000008>
The effect is that SIGIO is *not* disabled and C-g is detected and
works as normal.
For 21.1 Jan applied a patch to the above
http://www.xemacs.org/list-archives/xemacs-patches/199906/msg00000.html
-#if defined (I_SETSIG) && !defined(HPUX10)
+#if defined (I_SETSIG) && !defined(HPUX10) && !defined(LINUX)
now the fcntl () is executed instead and this works, i.e. SIGIO is
disabled and we rely on the slowed down C-g detection to work. Only
problem is it doesn't...
After 15 seconds the expected SIGALARM arrives and the X event queue
is inspected for C-g but for some reason the C-g is not found. In my
debugging run the C-g event was just not there. Another problem is
that the SIGALARM is generated only once (this is fixable I guess). If
I generate another couple of SIGALARMs by hand with kill then the C-g
eventually shows up in the queue and open-network-stream is quit.
Ben, can you comment on this? Is this how things are supposed to
work?
Gunnar, you might be interested in the latest patch by Yoshiki, which
seems to make exactly the change necessary for the above to work
right. (But then again, it might not, with XEmacs it's hard to tell.)
2000-11-06 Yoshiki Hayashi <yoshiki(a)xemacs.org>
* cmdloop.c (Fcommand_loop_1): Just add C-g to event queue.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Index: cmdloop.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/cmdloop.c,v
retrieving revision 1.9.2.4
diff -u -r1.9.2.4 cmdloop.c
--- cmdloop.c 2000/05/11 10:29:34 1.9.2.4
+++ cmdloop.c 2000/11/06 05:16:28
@@ -549,9 +549,13 @@
}
}
+#if 0 /* What's wrong with going through ordinary procedure of quit?
+ quitting here leaves overriding-terminal-local-map
+ when you type C-u C-u C-g. */
/* If ^G was typed before we got here (that is, before emacs was
idle and waiting for input) then we treat that as an interrupt. */
QUIT;
+#endif