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/