etspam
etspam

Reputation: 31

does popen in C block until the command is finished?

I've looked through stackoverflow, and read the man pages about popen to try to understand its behavior. My understanding from this is that it creates a pipe, forks off a child process, and then executes the command in the child process. However, I'm trying to figure out - does the command that gets executed run to completion before the popen returns? I'm doing something like this:

fp = popen(cmd_str, "r");

if (!fp) {
    ERR("Failed to execute cmd");
    return;
}

Say the cmd_str takes a few minutes to finish. Will the popen return immediately? I tried googling for the popen.c source code, and the ones I found seem to indicate that the parent process returns the FILE ptr, while the child process goes off and does an exec on the cmd_str. Popen returns NULL if the pipe failed, the fork failed, some malloc failed, or maybe there were bad args.

It doesn't appear to me that the popen call is actually blocking to see if the cmd_str finished execution - the source code I've found doesn't have anything where the parent process waits for the child process to finish. Is this is how popen works? I'm just trying to make sure that my understanding of this is correct.

Upvotes: 3

Views: 1335

Answers (2)

Nate Eldredge
Nate Eldredge

Reputation: 58032

On modern Unix-like systems, no, popen won't block. There's no reason for it to do so. It forks the child process and, in the parent, returns immediately, leaving the child to run independently. Reads/writes to the pipe may of course block when the pipe buffer is empty/full respectively, and pclose will block until the child terminates.

POSIX specifies that "After popen(), both the parent and the child process shall be capable of executing independently before either terminates."

There have been other systems in history that managed to emulate popen despite not really supporting either pipes or multitasking, and the answer for them was different. Under DOS, for instance, when you would popen for reading, it would spawn the command and run it to completion, with its output written to a temp file, before popen returned. Subsequent reads from the "pipe" would read from the temp file. Conversely, when you popened for writing, it would open a temp file and return immediately. Writes would go to the temp file, and pclose would actually spawn the command with its input redirected from the temp file, blocking until it finished. (After that it would deallocate the stream like fclose would do.)

Upvotes: 2

Luis Colorado
Luis Colorado

Reputation: 12668

The quick answer is No.

The popen(3) call has a pclose(3) call that actually does wait for the child to finish. As only until the child is finished we cannot know if the communications stream from the child has not ended. Anyway, you can fclose(3) the channel and this means the child will not be waited for, as you don't have any means of joining the child in any form (you don't have the child pid to make a guess)

Upvotes: 0

Related Questions