I could really use some advice from people who know a bit about Unix
APIs and Linux in particular (Martin? Jan? Ben?). Sorry for the
long-winded explanation, please bear with me.
The unrequest_sigio_on_device function is completely broken on Linux
AFAICT.
We have the following in sysdep.c:
----------------------------------------------------------------------
request_sigio_on_device (struct device *d)
{
int filedesc = DEVICE_INFD (d);
#if defined (I_SETSIG) && !defined(HPUX10) && !defined(LINUX)
{
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);
[...]
unrequest_sigio_on_device (struct device *d)
{
int filedesc = DEVICE_INFD (d);
#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 (on most variants I have seen) both I_SETSIG and FASYNC are
defined. Thus in request_sigio() we use the ioctl and in
unrequest_sigio() we use the fcntl. Surely, this is wrong?
I think Jan had a patch for 21.1 that added the !defined(LINUX) to
unrequest_sigio as well, so that we used fcntl in both cases. This
might be a good thing, since when we use the ioctl what actually
happens (according to strace) is:
ioctl(6, CDROMVOLCTRL, 0xbfffea84) = -1 EINVAL (Invalid argument)
ioctl(6, CDROMEJECT, 0) = -1 EINVAL (Invalid argument)
this is clearly rubbish. (Aside: shouldn't we check the return value of
ioctl() anyway?). So, what happens in the current code is that we never
manage to disable SIGIOs.
OK, so when I "fix" this (causing fcntl to be used in both cases)
another problems surfaces. The code that tries to check for C-g to
interrupt system-calls fails under X (I tried to debug
x_check_for_quit_char() but C-g never appeared in the X event queue --
no idea why). The result is that things like
(open-network-stream "bug" nil "10.0.0.42" 42)
cannot be interrupted and will hang xemacs permanently (this was
pointed out by Simon Josefsson last year and is IMHO the major bug in
21.1).
Why do we need to wrap the connect() call inside open-network-stream
in slow_down_interrupts/speed_up_interrupts anyway? The current code
where SIGIOs get delivered and interrupt connect() seems to work fine.
Any help with this is very much appreciated.
Gunnar
P.S.: This is mostly a repost of
http://list-archive.xemacs.org/xemacs-beta/200011/msg00035.html
to which nobody replied :-(