static int setup_fds(void) { if (fd_ctor(&g_fdi, 0, g_opts.fd[0], g_opts.fsync) < 0) if (fd_ctor_f(&g_fdi, 0, g_opts.file[0], g_opts.fsync) < 0) if (fd_ctor_s(&g_fdi, 0, &g_opts.sock[0], !g_opts.rline) < 0) if (fd_ctor(&g_fdi, 0, "0", 0) < 0) return -1; if (fd_ctor(&g_fdo, 1, g_opts.fd[1], g_opts.fsync) < 0) if (fd_ctor_f(&g_fdo, 1, g_opts.file[1], g_opts.fsync) < 0) if (fd_ctor_s(&g_fdo, 1, &g_opts.sock[1], 0) < 0) if (fd_ctor(&g_fdo, 1, "1", g_opts.fsync) < 0) goto out; fprintf (stderr, "\nPre-open input side:\n"); fd_info(&g_fdi); fprintf (stderr, "\nPre-open output side:\n"); fd_info(&g_fdo); if (g_opts.strict) fputs("\nStrict reblocking writes enabled.\n", stderr); fflush(stderr); return 0; out: fd_dtor(&g_fdi); return -1; }
/* Given pipe, plumb it to standard output, then execute Nth command */ static void exec_pipe_command(int ncmds, char ***cmds, Pipe output) { assert(ncmds >= 1); /* Fix stdout to write end of pipe */ err_remark("Pipe: r %d, w %d", output[0], output[1]); if (dup2(output[1], 1) != 1) err_sysexit("dup2(%d, %d) in %s()", output[1], 1, __func__); if (close(output[0]) != 0) err_sysexit("close(%d) in %s()", output[0], __func__); if (close(output[1]) != 0) err_sysexit("close(%d) in %s()", output[0], __func__); if (vflag) { open_fds(10); fd_info(0); err_remark("Execute: %s\n", cmds[ncmds - 1][0]); } exec_nth_command(ncmds, cmds); }
int main(int argc, char **argv) { int opt; char *argv0 = argv[0]; setvbuf(stderr, 0, _IOLBF, BUFSIZ); err_setarg0(argv[0]); sigchld_status(); while ((opt = getopt(argc, argv, "v")) != -1) { switch (opt) { case 'v': vflag = 1; break; default: err_usage("[-v] [cmd1 | cmd2 ...]"); break; } } argv += optind - 1; argc -= optind - 1; argv[0] = argv0; fd_info(0); if (argc == 1) { /* Run the built in pipe-line */ exec_pipeline(ncmds, cmds); } else { /* Run command line specified by user */ exec_arguments(argc, argv); } corpse_collector(); return(0); }
/* With the standard output plumbing sorted, execute Nth command */ static void exec_nth_command(int ncmds, char ***cmds) { assert(ncmds >= 1); if (ncmds > 1) { pid_t pid; Pipe input; if (pipe(input) != 0) err_sysexit("Failed to create pipe"); err_remark("Pipe: r %d, w %d", input[0], input[1]); if (vflag) open_fds(10); if ((pid = fork()) < 0) err_sysexit("Failed to fork"); if (pid == 0) { /* Child */ exec_pipe_command(ncmds - 1, cmds, input); } /* Fix standard input to read end of pipe */ if (dup2(input[0], 0) != 0) err_sysexit("dup2(%d, %d) in %s()", input[0], 0, __func__); if (close(input[0]) != 0) err_sysexit("close(%d) in %s()", input[0], __func__); if (close(input[1]) != 0) err_sysexit("close(%d) in %s()", input[0], __func__); } if (vflag) { open_fds(10); fd_info(0); err_remark("Execute: %s\n", cmds[ncmds - 1][0]); } execvp(cmds[ncmds - 1][0], cmds[ncmds - 1]); err_sysexit("Failed to exec %s", cmds[ncmds - 1][0]); /*NOTREACHED*/ }