Something is wrong here. Here is fifo_open in fs/fifo.c from linux
2.1.129. O_RDONLY does
if (retval && !--PIPE_READERS(*inode))
wake_up_interruptible(&PIPE_WAIT(*inode));
break;
when it gets interrupted by SIGTSTP. When that happens,
PIPE_READERS(*inode) == 0
Now O_WRONLY|O_NONBLOCK comes along. It finds out
PIPE_READERS(*inode) == 0
and returns -ENXIO. That is what I observed. Did I miss something here?
H.J.
---
static int fifo_open(struct inode * inode,struct file * filp)
{
int retval = 0;
unsigned long page;
switch( filp->f_mode ) {
case 1:
/*
* O_RDONLY
* POSIX.1 says that O_NONBLOCK means return with the FIFO
* opened, even when there is no process writing the FIFO.
*/
filp->f_op = &connecting_fifo_fops;
if (!PIPE_READERS(*inode)++)
wake_up_interruptible(&PIPE_WAIT(*inode));
if (!(filp->f_flags & O_NONBLOCK) && !PIPE_WRITERS(*inode)) {
PIPE_RD_OPENERS(*inode)++;
while (!PIPE_WRITERS(*inode)) {
if (signal_pending(current)) {
retval = -ERESTARTSYS;
break;
}
interruptible_sleep_on(&PIPE_WAIT(*inode));
}
if (!--PIPE_RD_OPENERS(*inode))
wake_up_interruptible(&PIPE_WAIT(*inode));
}
while (PIPE_WR_OPENERS(*inode))
interruptible_sleep_on(&PIPE_WAIT(*inode));
if (PIPE_WRITERS(*inode))
filp->f_op = &read_fifo_fops;
if (retval && !--PIPE_READERS(*inode))
wake_up_interruptible(&PIPE_WAIT(*inode));
break;
case 2:
/*
* O_WRONLY
* POSIX.1 says that O_NONBLOCK means return -1 with
* errno=ENXIO when there is no process reading the FIFO.
*/
if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode)) {
retval = -ENXIO;
break;
}
filp->f_op = &write_fifo_fops;
if (!PIPE_WRITERS(*inode)++)
wake_up_interruptible(&PIPE_WAIT(*inode));
if (!PIPE_READERS(*inode)) {
PIPE_WR_OPENERS(*inode)++;
while (!PIPE_READERS(*inode)) {
if (signal_pending(current)) {
retval = -ERESTARTSYS;
break;
}
interruptible_sleep_on(&PIPE_WAIT(*inode));
}
if (!--PIPE_WR_OPENERS(*inode))
wake_up_interruptible(&PIPE_WAIT(*inode));
}
while (PIPE_RD_OPENERS(*inode))
interruptible_sleep_on(&PIPE_WAIT(*inode));
if (retval && !--PIPE_WRITERS(*inode))
wake_up_interruptible(&PIPE_WAIT(*inode));
break;
case 3:
/*
* O_RDWR
* POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
* This implementation will NEVER block on a O_RDWR open, since
* the process can at least talk to itself.
*/
filp->f_op = &rdwr_fifo_fops;
if (!PIPE_READERS(*inode)++)
wake_up_interruptible(&PIPE_WAIT(*inode));
while (PIPE_WR_OPENERS(*inode))
interruptible_sleep_on(&PIPE_WAIT(*inode));
if (!PIPE_WRITERS(*inode)++)
wake_up_interruptible(&PIPE_WAIT(*inode));
while (PIPE_RD_OPENERS(*inode))
interruptible_sleep_on(&PIPE_WAIT(*inode));
break;
default:
retval = -EINVAL;
}
if (retval || PIPE_BASE(*inode))
return retval;
page = __get_free_page(GFP_KERNEL);
if (PIPE_BASE(*inode)) {
free_page(page);
return 0;
}
if (!page)
return -ENOMEM;
PIPE_LOCK(*inode) = 0;
PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
PIPE_BASE(*inode) = (char *) page;
return 0;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/