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.
I am afraid I don't know enough about X (yet) to fix this but I'll
keep digging.
BTW do we really still need to disable SIGIO during connect()? The
reference to kernel bugs on ultrix don't strike me as a good reason.
Help and advice as always welcome.
Gunnar