示例#1
0
int
main (void)
{
  const char *file = "test-cloexec.tmp";
  int fd = creat (file, 0600);
  int fd2;

  /* Assume std descriptors were provided by invoker.  */
  ASSERT (STDERR_FILENO < fd);
  ASSERT (is_inheritable (fd));

  /* Normal use of set_cloexec_flag.  */
  ASSERT (set_cloexec_flag (fd, true) == 0);
#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
  ASSERT (!is_inheritable (fd));
#endif
  ASSERT (set_cloexec_flag (fd, false) == 0);
  ASSERT (is_inheritable (fd));

  /* Normal use of dup_cloexec.  */
  fd2 = dup_cloexec (fd);
  ASSERT (fd < fd2);
  ASSERT (!is_inheritable (fd2));
  ASSERT (close (fd) == 0);
  ASSERT (dup_cloexec (fd2) == fd);
  ASSERT (!is_inheritable (fd));
  ASSERT (close (fd2) == 0);

  /* On systems that distinguish between text and binary mode,
     dup_cloexec reuses the mode of the source.  */
  setmode (fd, O_BINARY);
  ASSERT (is_mode (fd, O_BINARY));
  fd2 = dup_cloexec (fd);
  ASSERT (fd < fd2);
  ASSERT (is_mode (fd2, O_BINARY));
  ASSERT (close (fd2) == 0);
  setmode (fd, O_TEXT);
  ASSERT (is_mode (fd, O_TEXT));
  fd2 = dup_cloexec (fd);
  ASSERT (fd < fd2);
  ASSERT (is_mode (fd2, O_TEXT));
  ASSERT (close (fd2) == 0);

  /* Test error handling.  */
  errno = 0;
  ASSERT (set_cloexec_flag (-1, false) == -1);
  ASSERT (errno == EBADF);
  errno = 0;
  ASSERT (set_cloexec_flag (10000000, false) == -1);
  ASSERT (errno == EBADF);
  errno = 0;
  ASSERT (set_cloexec_flag (fd2, false) == -1);
  ASSERT (errno == EBADF);
  errno = 0;
  ASSERT (dup_cloexec (-1) == -1);
  ASSERT (errno == EBADF);
  errno = 0;
  ASSERT (dup_cloexec (10000000) == -1);
  ASSERT (errno == EBADF);
  errno = 0;
  ASSERT (dup_cloexec (fd2) == -1);
  ASSERT (errno == EBADF);

  /* Clean up.  */
  ASSERT (close (fd) == 0);
  ASSERT (unlink (file) == 0);

  return 0;
}
int
main (void)
{
  const char *file = "test-dup2.tmp";
  char buffer[1];
  int fd = open (file, O_CREAT | O_TRUNC | O_RDWR, 0600);

  /* Assume std descriptors were provided by invoker.  */
  ASSERT (STDERR_FILENO < fd);
  ASSERT (is_open (fd));
  /* Ignore any other fd's leaked into this process.  */
  close (fd + 1);
  close (fd + 2);
  ASSERT (!is_open (fd + 1));
  ASSERT (!is_open (fd + 2));

  /* Assigning to self must be a no-op.  */
  ASSERT (dup2 (fd, fd) == fd);
  ASSERT (is_open (fd));

  /* The source must be valid.  */
  errno = 0;
  ASSERT (dup2 (-1, fd) == -1);
  ASSERT (errno == EBADF);
  errno = 0;
  ASSERT (dup2 (99, fd) == -1);
  ASSERT (errno == EBADF);
  errno = 0;
  ASSERT (dup2 (AT_FDCWD, fd) == -1);
  ASSERT (errno == EBADF);
  ASSERT (is_open (fd));

  /* If the source is not open, then the destination is unaffected.  */
  errno = 0;
  ASSERT (dup2 (fd + 1, fd + 1) == -1);
  ASSERT (errno == EBADF);
  ASSERT (!is_open (fd + 1));
  errno = 0;
  ASSERT (dup2 (fd + 1, fd) == -1);
  ASSERT (errno == EBADF);
  ASSERT (is_open (fd));

  /* The destination must be valid.  */
  errno = 0;
  ASSERT (dup2 (fd, -2) == -1);
  ASSERT (errno == EBADF);
  errno = 0;
  ASSERT (dup2 (fd, 10000000) == -1);
  ASSERT (errno == EBADF);

  /* Using dup2 can skip fds.  */
  ASSERT (dup2 (fd, fd + 2) == fd + 2);
  ASSERT (is_open (fd));
  ASSERT (!is_open (fd + 1));
  ASSERT (is_open (fd + 2));

  /* Verify that dup2 closes the previous occupant of a fd.  */
  ASSERT (open ("/dev/null", O_WRONLY, 0600) == fd + 1);
  ASSERT (dup2 (fd + 1, fd) == fd);
  ASSERT (close (fd + 1) == 0);
  ASSERT (write (fd, "1", 1) == 1);
  ASSERT (dup2 (fd + 2, fd) == fd);
  ASSERT (lseek (fd, 0, SEEK_END) == 0);
  ASSERT (write (fd + 2, "2", 1) == 1);
  ASSERT (lseek (fd, 0, SEEK_SET) == 0);
  ASSERT (read (fd, buffer, 1) == 1);
  ASSERT (*buffer == '2');

#if GNULIB_TEST_CLOEXEC
  /* Any new fd created by dup2 must not be cloexec.  */
  ASSERT (close (fd + 2) == 0);
  ASSERT (dup_cloexec (fd) == fd + 1);
  ASSERT (!is_inheritable (fd + 1));
  ASSERT (dup2 (fd + 1, fd + 1) == fd + 1);
  ASSERT (!is_inheritable (fd + 1));
  ASSERT (dup2 (fd + 1, fd + 2) == fd + 2);
  ASSERT (!is_inheritable (fd + 1));
  ASSERT (is_inheritable (fd + 2));
  errno = 0;
  ASSERT (dup2 (fd + 1, -1) == -1);
  ASSERT (errno == EBADF);
  ASSERT (!is_inheritable (fd + 1));
#endif

  /* On systems that distinguish between text and binary mode, dup2
     reuses the mode of the source.  */
  setmode (fd, O_BINARY);
  ASSERT (is_mode (fd, O_BINARY));
  ASSERT (dup2 (fd, fd + 1) == fd + 1);
  ASSERT (is_mode (fd + 1, O_BINARY));
  setmode (fd, O_TEXT);
  ASSERT (is_mode (fd, O_TEXT));
  ASSERT (dup2 (fd, fd + 1) == fd + 1);
  ASSERT (is_mode (fd + 1, O_TEXT));

  /* Clean up.  */
  ASSERT (close (fd + 2) == 0);
  ASSERT (close (fd + 1) == 0);
  ASSERT (close (fd) == 0);
  ASSERT (unlink (file) == 0);

  return 0;
}
示例#3
0
int
main (void)
{
  int i;
  int fd;

  /* We close fd 2 later, so save it in fd 10.  */
  if (dup2 (STDERR_FILENO, BACKUP_STDERR_FILENO) != BACKUP_STDERR_FILENO
      || (myerr = fdopen (BACKUP_STDERR_FILENO, "w")) == NULL)
    return 2;

  /* Create file for later checks.  */
  fd = creat (witness, 0600);
  ASSERT (STDERR_FILENO < fd);

  /* Four iterations, with progressively more standard descriptors
     closed.  */
  for (i = -1; i <= STDERR_FILENO; i++)
    {
      if (0 <= i)
        ASSERT (close (i) == 0);

      /* Detect errors.  */
      errno = 0;
      ASSERT (dup (-1) == -1);
      ASSERT (errno == EBADF);
      errno = 0;
      ASSERT (dup (10000000) == -1);
      ASSERT (errno == EBADF);
      close (fd + 1);
      errno = 0;
      ASSERT (dup (fd + 1) == -1);
      ASSERT (errno == EBADF);

      /* Preserve text vs. binary.  */
      setmode (fd, O_BINARY);
      ASSERT (dup (fd) == fd + 1);
      ASSERT (is_open (fd + 1));
      ASSERT (is_inheritable (fd + 1));
      ASSERT (is_mode (fd + 1, O_BINARY));

      ASSERT (close (fd + 1) == 0);
      setmode (fd, O_TEXT);
      ASSERT (dup (fd) == fd + 1);
      ASSERT (is_open (fd + 1));
      ASSERT (is_inheritable (fd + 1));
      ASSERT (is_mode (fd + 1, O_TEXT));

      /* Create cloexec copy.  */
      ASSERT (close (fd + 1) == 0);
      ASSERT (fd_safer_flag (dup_cloexec (fd), O_CLOEXEC) == fd + 1);
      ASSERT (set_cloexec_flag (fd + 1, true) == 0);
      ASSERT (is_open (fd + 1));
      ASSERT (!is_inheritable (fd + 1));
      ASSERT (close (fd) == 0);

      /* dup always creates inheritable copies.  Also, check that
         earliest slot past std fds is used.  */
      ASSERT (dup (fd + 1) == fd);
      ASSERT (is_open (fd));
      ASSERT (is_inheritable (fd));
      ASSERT (close (fd + 1) == 0);
    }

  /* Cleanup.  */
  ASSERT (close (fd) == 0);
  ASSERT (unlink (witness) == 0);

  return 0;
}