In C come si reindirizza stdin / stdout / stderr ai file quando si esegue una chiamata execvp () o simile?

Ho il codice seguente:

pid_t pid = fork(); if (pid == -1) { // ... } else if (pid == 0) { stdin = someopenfile; stdout = someotherfile; stderr = somethirdopenfile; execvp(args[0], args); // handle error ... } else { // ... } 

Il problema è che l’input / output della chiamata execvp() è ancora la console, piuttosto che i file. Chiaramente sto facendo qualcosa di sbagliato, qual è il modo giusto per farlo?

Il modo giusto per farlo è sostituire i descrittori di file STDIN_FILENO , STDOUT_FILENO e STDERR_FILENO con i file aperti usando dup2() . Dovresti anche chiudere i file originali nel processo figlio:

 else if (pid == 0) { dup2(fileno(someopenfile), STDIN_FILENO); dup2(fileno(someotherfile), STDOUT_FILENO); dup2(fileno(somethirdopenfile), STDERR_FILENO); fclose(someopenfile); fclose(someotheropenfile); fclose(somethirdopenfile); execvp(args[0], args); // handle error ... } 

Dai un’occhiata alla funzione freopen .

Ho dovuto fare qualcosa di simile con stdout e ho scritto due funzioni che fanno il lavoro per me:

 static int fd; static fpos_t pos; void switchStdout(const char *newStream) { fflush(stdout); fgetpos(stdout, &pos); fd = dup(fileno(stdout)); freopen(newStream, "w", stdout); } void revertStdout() { fflush(stdout); dup2(fd, fileno(stdout)); close(fd); clearerr(stdout); fsetpos(stdout, &pos); } 

Puoi usare questo quando stdin, stdout, stderr sono terminali-

 //change stdin,stdout,stderr freopen("new_stdin","r",stdin); freopen("new_stdout","r",stdout); freopen("new_stderr","r",stderr); //----do something; //reset stdin,stdout,stderr freopen("/dev/tty","r",stdin); freopen("/dev/tty","r",stdout); freopen("/dev/tty","r",stderr);