En C, ¿cómo redirige stdin / stdout / stderr a los archivos al hacer una llamada execvp () o similar?

Tengo el siguiente código:

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

El problema es que la entrada / salida de la llamada execvp() sigue siendo la consola, en lugar de los archivos. Claramente estoy haciendo algo mal, ¿cuál es la forma correcta de hacer esto?

La forma correcta de hacerlo es reemplazar los descriptores de archivo STDIN_FILENO , STDOUT_FILENO y STDERR_FILENO con los archivos abiertos usando dup2() . También debe cerrar los archivos originales en el proceso hijo:

 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 ... } 

Eche un vistazo a la función freopen .

Tuve que hacer algo similar con stdout y escribí dos funciones que hacen el trabajo por mí:

 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); } 

Puede usar esto cuando stdin, stdout, stderr son terminales-

 //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);