#include #include #include #include #include #include #include int main (const int argc, char *argv[], char *envp[]) { if (argc != 2) { fprintf (stderr, "Usage: %s -1\n", argv[0]); exit (1); } const int flag = atoi (argv[1]); if (flag == -1) { const int fd = open ("/etc/passwd", O_RDONLY); if (fd == -1) { perror ("/etc/passwd"); exit (1); } if (fcntl (fd, F_SETFD, FD_CLOEXEC) == -1) { perror ("fcntl"); exit (1); } pid_t pid = fork (); switch (pid) { case -1: perror ("fork"); exit (1); case 0: // child { char buf[BUFSIZ]; sprintf (buf, "%d", fd); argv[1] = buf; execve (argv[0], argv, envp); } break; default: // parent { int status; if (wait (&status) == -1) { perror ("wait ()"); exit (1); } } break; } } else { char buf[BUFSIZ]; ssize_t len = read (flag, buf, sizeof (buf)); if (len == -1) { perror ("/etc/passwd"); exit (1); } write (1, buf, len); } return 0; }