The POSIX testsuite found another Linux kernel bug. This time is the
interaction between fifo open and signal:
# gcc fifo.c
# a.out 1
# a.out
parent: open: Device not configured
The problem is the child is waiting in fifo_open in kernel and is
stopped by a signal. As the result, the parant fifo open returns
ENXIO. It is incorrect. The kernel should notice that there a
process doing fifo_open but was stopped. I don't think it is too
hard to fix.
Thanks.
-- H.J. Lu (hjl@gnu.org) ---- #include <signal.h> #include <errno.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/wait.h> #include <sys/stat.h>#define WAITTIME 5
#define FIFO_FILE "test.fifo"
static int fd = -1;
static void cleanup () { if (fd >= 0) close (fd); unlink (FIFO_FILE); }
static void do_open () { int fd;
fd = open(FIFO_FILE, O_RDONLY); if (fd < 0) perror ("child: open"); }
static void child () { if(setpgid((pid_t)0, (pid_t)0) < 0) { perror ("setpgid"); exit (1); } do_open (); exit (0); }
int main (int argc, char **argv) { int ret; int status; int sel; pid_t child_pid;
cleanup (); if (mkfifo (FIFO_FILE, S_IRWXU|S_IRWXG|S_IRWXO) != 0) { perror ("mkfifo"); exit (1); }
sel = argc == 1 ? 0 : atoi (argv [1]);
switch (child_pid = fork ()) { case 0: /* Child */ child (); break;
case -1: perror ("fork"); cleanup (sel); exit (1); break;
default: break; }
sleep (WAITTIME);
if (sel == 0) { if(kill(child_pid, SIGTSTP)) { perror ("kill"); cleanup (); exit (1); } sleep (WAITTIME); }
fd = open(FIFO_FILE, O_WRONLY|O_NONBLOCK); if (sel == 0) { if (fd < 0) { perror ("parent: open"); if(kill(child_pid, SIGKILL)) { perror ("kill"); cleanup (); exit (1); } } else { if(kill(child_pid, SIGCONT)) { perror ("kill"); cleanup (); exit (1); } } } ret = waitpid (child_pid, &status, WUNTRACED); if (ret < 0) { perror ("waitpid"); exit (1); }
cleanup (); return ret; }
- 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/