c - How to use perror with dup2? -
i'm adding error handling small c program , i've gotten work fork , execvp not dup2.
int spawn_proc (int in, int out, struct command *cmd) { pid_t pid; if ((pid = fork ()) == 0) { if (in != 0) { dup2 (in, 0); close (in); } if (out != 1) { dup2 (out, 1); close (out); } if (execvp(cmd->argv [0], (char * const *)cmd->argv) < 0) { perror("execvp failed"); exit(1); } } else if (pid < 0) { perror("fork failed"); exit(1); } return pid; }
how should perror used dup2 ? asked before don't think answer dup2 correct since program exits error dup2 if run no arguments if use code answer here.
my c program this.
#include <sys/types.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> struct command { const char **argv; }; /* helper function spawns processes */ int spawn_proc (int in, int out, struct command *cmd) { pid_t pid; if ((pid = fork ()) == 0) { if (in != 0) { dup2 (in, 0); close (in); } if (out != 1) { dup2 (out, 1); close (out); } if (execvp(cmd->argv [0], (char * const *)cmd->argv) < 0) { perror("execvp failed"); exit(1); } } else if (pid < 0) { perror("fork failed"); exit(1); } return pid; } /* helper function forks pipes */ int fork_pipes (int n, struct command *cmd) { int i; int in, fd [2]; (i = 0; < n - 1; ++i) { pipe (fd); spawn_proc (in, fd [1], cmd + i); close (fd [1]); in = fd [0]; } dup2 (in, 0); return execvp (cmd [i].argv [0], (char * const *)cmd [i].argv); } int main (int argc, char ** argv) { int i; if (argc == 1) { /* there no arguments */ const char *printenv[] = { "printenv", 0}; const char *sort[] = { "sort", 0 }; const char *less[] = { "less", 0 }; struct command cmd [] = { {printenv}, {sort}, {less} }; return fork_pipes (3, cmd); } if (argc > 1) { /* i'd argument */ if (strncmp(argv[1], "cd", 2) && strncmp(argv[1], "exit", 2)) { char *tmp; int len = 1; for( i=1; i<argc; i++) { len += strlen(argv[i]) + 2; } tmp = (char*) malloc(len); tmp[0] = '\0'; int pos = 0; for( i=1; i<argc; i++) { pos += sprintf(tmp+pos, "%s%s", (i==1?"":"|"), argv[i]); } const char *printenv[] = { "printenv", 0}; const char *grep[] = { "grep", "-e", tmp, null}; const char *sort[] = { "sort", 0 }; const char *less[] = { "less", 0 }; struct command cmd [] = { {printenv}, {grep}, {sort}, {less} }; return fork_pipes (4, cmd); free(tmp); } else if (! strncmp(argv[1], "cd", 2)) { /* change directory */ printf("change directory %s\n" , argv[2]); chdir(argv[2]); } else if (! strncmp(argv[1], "exit", 2)) { /* change directory */ printf("exit\n"); exit(0); } } exit(0); }
update
when run code, program diesn't display output when run no arguments. wrong?
int spawn_proc (int in, int out, struct command *cmd) { pid_t pid; if ((pid = fork ()) == 0) { if (in != 0) { if (dup2(in, 0) == -1) { perror("dup2 failed"); exit(1); } dup2 (in, 0); close (in); } if (out != 1) { dup2 (out, 1); close (out); } if (execvp(cmd->argv [0], (char * const *)cmd->argv) < 0) { perror("execvp failed"); exit(1); } } else if (pid < 0) { perror("fork failed"); exit(1); } return pid; }
you use same other system calls. check error return value (-1
), , call perror
display error.
if (dup2(in, 0) == -1) { perror("dup2 failed"); exit(1); }