Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 31 Jan 1996 15:29:45 +1100
From:      Bruce Evans <bde@zeta.org.au>
To:        current@freebsd.org, dyson@freebsd.org
Subject:   new pipes fail several tests #3
Message-ID:  <199601310429.PAA13400@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
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 <sys/types.h>
#include <sys/wait.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

#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;
}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199601310429.PAA13400>