From owner-freebsd-current Tue Jan 30 20:34:56 1996 Return-Path: owner-current Received: (from root@localhost) by freefall.freebsd.org (8.7.3/8.7.3) id UAA12065 for current-outgoing; Tue, 30 Jan 1996 20:34:56 -0800 (PST) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by freefall.freebsd.org (8.7.3/8.7.3) with SMTP id UAA12023 Tue, 30 Jan 1996 20:34:36 -0800 (PST) Received: (from bde@localhost) by godzilla.zeta.org.au (8.6.9/8.6.9) id PAA13400; Wed, 31 Jan 1996 15:29:45 +1100 Date: Wed, 31 Jan 1996 15:29:45 +1100 From: Bruce Evans Message-Id: <199601310429.PAA13400@godzilla.zeta.org.au> To: current@freebsd.org, dyson@freebsd.org Subject: new pipes fail several tests #3 Sender: owner-current@freebsd.org Precedence: bulk The fixes for #1 and #2 seem to work. Thanks. New pipes are uninterruptible, unlike old pipes and named pipes. The SA_RESTART bit in sa.sa_flags is cleared so no syscalls should be restarted when the signal occurs. This is probably because sys_pipe.c converts all or almost all of the nonzero returned by tsleep() to ERESTART. The signal catcher wasn't called. I think it should be called even for syscalls that are restarted. Bruce #include #include #include #include #include #include #include #include #define check(what, expected) assert((what, expected)) sig_atomic_t caught; void catch(int s) { caught = 1; } int main(void) { char buf[1]; int fd[2]; struct sigaction osa, sa; pid_t pid, rpid; int r; int status; r = pipe(fd); check("pipe", r == 0); pid = fork(); check("fork", pid != -1); switch(pid) { case 0: alarm(5); sa.sa_handler = catch; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; r = sigaction(SIGUSR1, &sa, &osa); check("sigaction", r == 0); #ifdef OK sleep(3); check("sleep", caught == 1); #else r = read(fd[0], buf, sizeof buf); printf("read %d bytes, errno = %d, caught = %d\n", r, errno, caught); check("read", r == -1); check("read", errno == EINTR); check("read", caught == 1); #endif r = sigaction(SIGUSR1, &osa, NULL); check("sigaction2", r == 0); r = close(fd[0]); check("close", r == 0); r = close(fd[1]); check("close2", r == 0); break; default: sleep(1); r = close(fd[0]); check("close3", r == 0); r = kill(pid, SIGUSR1); check("kill", r == 0); rpid = wait(&status); printf("wait returned %ld, status = %d, errno = %d\n", rpid, status, errno); check("wait", rpid == pid); check("wait", status == 0); break; } return 0; }