Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to control popen stdin, stdout, stderr redirection?

Tags:

c

unix

I am confused about how popen() redirects stdin, stdout and stderr of the child process in unix. The man page on popen() is not very clear in this regard. The call

FILE *p = popen("/usr/bin/foo", "w"); 

forks a child process and executes a shell with arguments "-c", "/usr/bin/foo", and redirects stdin of this shell (which is redirected stdin of foo), stdout to p. But what happens with stderr? What is the general principle behind it?

I noticed that, if I open a file in foo (using fopen, socket, accept etc.), and the parent process has no stdout, it gets assigned the next available file number, which is 1 and so on. This delivers unexpected results from calls like fprintf(stderr, ...).

It can be avoided by writing

FILE *p = popen("/usr/bin/foo 2>/dev/null", "w"); 

in the parent program, but are their better ways?

like image 540
Dong Hoon Avatar asked Nov 11 '08 10:11

Dong Hoon


People also ask

How do you redirect stdin stdout and stderr to a file?

Redirecting stdout and stderr to a file: The I/O streams can be redirected by putting the n> operator in use, where n is the file descriptor number. For redirecting stdout, we use “1>” and for stderr, “2>” is added as an operator.

What are stdin stdout and stderr how are they used?

stdin − It stands for standard input, and is used for taking text as an input. stdout − It stands for standard output, and is used to text output of any command you type in the terminal, and then that output is stored in the stdout stream. stderr − It stands for standard error.

What is the difference between stdin stdout and stderr?

If my understanding is correct, stdin is the file in which a program writes into its requests to run a task in the process, stdout is the file into which the kernel writes its output and the process requesting it accesses the information from, and stderr is the file into which all the exceptions are entered.

Which is used to redirect both stdout and stderr?

Understanding the concept of redirections and file descriptors is very important when working on the command line. To redirect stderr and stdout , use the 2>&1 or &> constructs.


2 Answers

popen(3) is just a library function, which relies on fork(2) and pipe(2) to do the real work.

However pipe(2) can only create unidirectional pipes. To send the child process input, and also capture the output, you need to open two pipes.

If you want to capture the stderr too, that's possible, but then you'll need three pipes, and a select loop to arbitrate reads between the stdout and stderr streams.

There's an example here for the two-pipe version.

like image 107
Alnitak Avatar answered Oct 13 '22 01:10

Alnitak


simple idea: why not add "2>&1" to the command string to force the bash to redirect stderr to stdout (OK, writing to stdin still is not possible but at least we get stderr and stdout into our C program).

like image 44
martin Avatar answered Oct 13 '22 02:10

martin