In C, how do you redirect stdin / stdout / stderr to files when execvp () or a similar call is made?

I have the following code:

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

The problem is that the input / output of the execvp() call is still the console, not the files. It’s clear that I am doing something wrong, what is the right way to do this?

+18
source share
3 answers

The correct way to do this is to replace the file descriptors STDIN_FILENO , STDOUT_FILENO and STDERR_FILENO open files using dup2() . Then you must close the source files in the child process:

 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 ... } 
+39
source

Take a look at freopen .

I needed to do something similar with stdout and wrote two functions that do my job:

 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); } 
+5
source

You can use this when stdin, stdout, stderr are terminals -

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

Source: https://habr.com/ru/post/1272152/


All Articles