Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Standard approach to determine success or failure of fork/exec (while parent is running simultaneously)?

Tags:

fork

unix

exec

I made a program using fork() and exec*(). The problem is I can't determine success or failure of exec() from parent process because it's on separated child process. I think kind of signaling can be used to check this state, but I have no idea about this.

  1. What's the recommended/standard/widely-used way to check this?
  2. And what's the pitfalls that I have to care about while doing this?

Question Detail Update (Sorry for omission of important detail)

I want to keep both processes are running so I can't just wait exiting of child process. In other words, I want to be notified about the child process' exec success or failure.

like image 326
eonil Avatar asked Sep 25 '11 16:09

eonil


People also ask

How do I know if Execl was successful?

You can arrange give the child one end of a pipe() , set to close-on-exec. After the execl() fails (i.e. if the call returns), the child will write() to the pipe. If the parent receives anything on its end of the pipe (checking with poll() or similar), then it knows the child has failed.

Why do we need separate fork () and exec () system calls instead of one combined system call that does both?

The main reason is likely that the separation of the fork() and exec() steps allows arbitrary setup of the child environment to be done using other system calls.

How are fork () and exec () system calls different from normal system function calls in terms of their call return behavior?

A call to fork() returns once or twice - the latter on success where it returns once in the parent and once in the child, the former on failure where it simply returns once in the parent. A call to exec() will return on failure but, if successful, the current process is simply overwritten with a new program.


1 Answers

Your parent process can use the pid of the child process to detect that it is alive or has exited (and can disambiguate the error code, and died-because-of-signal errors, see waitpid). You can use certain error codes or signals to notify the parent about specific error cases (e.g., in the forked child before the exec), but for a completely generic child, you may not be able to reserve any exit codes or signals (since the parent won't be able to tell if the exec succeeded and then the child exited with those values).

Another approach often used is to create a pipe fd pair (see the 'pipe' syscall), and pass one end to the child (generally the write end) and the other to the parent. The child can use this to send specific error codes to the parent. And the parent can detect premature termination if the pipe is closed without getting any data. There are some pitfalls: SIGPIPE will be sent to the parent if it reads on a pipe with no active writers, and using up an fd (other than stdin/stdout/stderr) in a child process may confuse some badly-written child processes (though close-on-exec can help fix that).

In general, all the code I've seen to make fork+exec robust is pretty hacky.

like image 169
P.T. Avatar answered Oct 18 '22 12:10

P.T.