Lost O_NONBLOCK (Bug?)

From: Jason Gunthorpe (jgg@debian.org)
Date: Mon Apr 09 2001 - 23:44:02 EST


Hi,

I've run into the following weird behavior on my system with 2.4.0. I have
the following code:

if (fork() == 0)
{
    int Flags,dummy;
    if ((Flags = fcntl(STDIN_FILENO,F_GETFL,dummy)) < 0)
        _exit(100);
    if (fcntl(STDIN_FILENO,F_SETFL,Flags | O_NONBLOCK) < 0)
         _exit(100);
    while (read(STDIN_FILENO,&dummy,1) == 1);
    if (fcntl(STDIN_FILENO,F_SETFL,Flags & (~(long)O_NONBLOCK)) < 0)
         _exit(100);
 
    // exec something
}

Which works fine, unless the parent process was backgrounded by the shell
(^Z then bg). If that is the case then the O_NONBLOCK seems to be lost. I
straced this:

fcntl(0, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(0, F_SETFL, O_RDWR|O_NONBLOCK) = 0
read(0, 0xbfffea38, 1) = ? ERESTARTSYS (To be restarted)
--- SIGTTIN (Stopped (tty input)) ---
--- SIGTTIN (Stopped (tty input)) ---
read(0, 0xbfffea38, 1) = ? ERESTARTSYS (To be restarted)
--- SIGTTIN (Stopped (tty input)) ---
--- SIGTTIN (Stopped (tty input)) ---
[.. etc, again and again in a tight loop ..]
--- SIGTTIN (Stopped (tty input)) ---
--- SIGTTIN (Stopped (tty input)) ---
read(0,

The last read was after the process was forgrounded. The read waits
forever, the non-block flag seems to have gone missing. It is also a
little odd I think that it repeated to get SIGTTIN which was never
actually delivered to the program.. Shouldn't SIGTTIN suspend the process?

The signal mask from /proc/xx/status (the child) looks like:

SigPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 8000000000000000
SigCgt: 0000000000000000

Is this the expected behavior of the kernel?

Thanks,
Jason
Please CC me, I'm not on l-k today.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Apr 15 2001 - 21:00:12 EST