int main () { int use_nonblocking; int use_cloexec; for (use_nonblocking = 0; use_nonblocking <= !!O_NONBLOCK; use_nonblocking++) for (use_cloexec = 0; use_cloexec <= !!O_CLOEXEC; use_cloexec++) { int o_flags; int fd[2]; o_flags = 0; if (use_nonblocking) o_flags |= O_NONBLOCK; if (use_cloexec) o_flags |= O_CLOEXEC; fd[0] = -1; fd[1] = -1; ASSERT (pipe2 (fd, o_flags) >= 0); ASSERT (fd[0] >= 0); ASSERT (fd[1] >= 0); ASSERT (fd[0] != fd[1]); ASSERT (is_open (fd[0])); ASSERT (is_open (fd[1])); if (use_cloexec) { ASSERT (is_cloexec (fd[0])); ASSERT (is_cloexec (fd[1])); } else { ASSERT (!is_cloexec (fd[0])); ASSERT (!is_cloexec (fd[1])); } if (use_nonblocking) { ASSERT (get_nonblocking_flag (fd[0]) == 1); ASSERT (get_nonblocking_flag (fd[1]) == 1); } else { ASSERT (get_nonblocking_flag (fd[0]) == 0); ASSERT (get_nonblocking_flag (fd[1]) == 0); } ASSERT (close (fd[0]) == 0); ASSERT (close (fd[1]) == 0); } return 0; }
int main () { int fd[2]; fd[0] = -1; fd[1] = -1; ASSERT (pipe (fd) >= 0); ASSERT (fd[0] >= 0); ASSERT (fd[1] >= 0); ASSERT (fd[0] != fd[1]); ASSERT (is_open (fd[0])); ASSERT (is_open (fd[1])); ASSERT (!is_cloexec (fd[0])); ASSERT (!is_cloexec (fd[1])); ASSERT (!is_nonblocking (fd[0])); ASSERT (!is_nonblocking (fd[1])); return 0; }
int main () { int use_cloexec; #if O_CLOEXEC for (use_cloexec = 0; use_cloexec <= 1; use_cloexec++) #else use_cloexec = 0; #endif { const char *file = "test-dup3.tmp"; int fd = open (file, O_CREAT | O_TRUNC | O_RDWR, 0600); int o_flags; char buffer[1]; o_flags = 0; #if O_CLOEXEC if (use_cloexec) o_flags |= O_CLOEXEC; #endif /* 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 is invalid. */ errno = 0; ASSERT (dup3 (fd, fd, o_flags) == -1); ASSERT (errno == EINVAL); ASSERT (is_open (fd)); /* If the source is not open, then the destination is unaffected. */ errno = 0; ASSERT (dup3 (fd + 1, fd + 2, o_flags) == -1); ASSERT (errno == EBADF); ASSERT (!is_open (fd + 2)); errno = 0; ASSERT (dup3 (fd + 1, fd, o_flags) == -1); ASSERT (errno == EBADF); ASSERT (is_open (fd)); /* The destination must be valid. */ errno = 0; ASSERT (dup3 (fd, -2, o_flags) == -1); ASSERT (errno == EBADF); errno = 0; ASSERT (dup3 (fd, 10000000, o_flags) == -1); ASSERT (errno == EBADF); /* Using dup3 can skip fds. */ ASSERT (dup3 (fd, fd + 2, o_flags) == fd + 2); ASSERT (is_open (fd)); ASSERT (!is_open (fd + 1)); ASSERT (is_open (fd + 2)); if (use_cloexec) ASSERT (is_cloexec (fd + 2)); else ASSERT (!is_cloexec (fd + 2)); /* Verify that dup3 closes the previous occupant of a fd. */ ASSERT (open ("/dev/null", O_WRONLY, 0600) == fd + 1); ASSERT (dup3 (fd + 1, fd, o_flags) == fd); ASSERT (close (fd + 1) == 0); ASSERT (write (fd, "1", 1) == 1); ASSERT (dup3 (fd + 2, fd, o_flags) == 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'); /* Clean up. */ ASSERT (close (fd + 2) == 0); ASSERT (close (fd) == 0); ASSERT (unlink (file) == 0); } return 0; }