tags:

views:

156

answers:

4

if(pid == 0)
{
      execvp(cmd, args);
      // printf("hello"); // apparently, putting this or not does not work.
      _exit(-1);
}
else
{
      // parent process work
}

"execvp()" replaces the current program with the to-be-execed program (of course in the same process context). So, putting, say, any printf() calls after execvp() won't work. That is what the docs say, and I have verified it as well.

But then, why is _exit() needed..? Does it so happen that the control DOES return to statements post execvp() ?

I will be grateful for any pointers.

Thanks

+4  A: 

The function will return if it has failed.

If one of the exec functions returns to the calling process image, an error has occurred; the return value shall be -1, and errno shall be set to indicate the error.

The _exit() allows terminating the process properly and return an exit code, even if exec fails.

KennyTM
Thanks KennyTM.Ok, so how are the malloc'ed() variables supposed to be freed, in the case when "args" have been dynamically allocated?
Ajay Garg
@Ajay: The OS should clean them up when the process ends.
KennyTM
+1  A: 

If execvp fails, _exit will be called.

execvp's man page says:

Return Value
If any of the exec() functions returns, an error will have occurred. The return value is -1, and the global variable errno will be set to indicate the error.

Bertrand Marron
A: 

One thing to note, you generally don't want a process' exit status to be signed (if portability matters). While exec() is free to return -1 on failure, its returning that so you can handle that failure within the child code.

The actual _exit() status of the child should be 0 - 255, depending on what errno was raised.

Tim Post
+1  A: 

The execve() syscall can fail. The classic reason for doing this would be if the file isn't there or isn't executable. execvp() wraps around execve() to add path searching and default environment handling (virtually always what you want!) and so it adds in another few failure modes, notably trying to run something with a simple name that's not on the user's path. In any case, failure is failure and there's not a lot you can do when it happens except report that it has gone wrong and Get the (now useless) child process Out Of Dodge. (The simplest error reporting method is to print an error message, perhaps with perror(), but there are others.)

The reason why you need _exit() as opposed to the more normal exit() is because you want to quit the child process but you do not want to run any registered cleanup code associated with the parent process. OK, a lot of it might be harmless, but doing things like writing goodbye messages to a socket or something would be bad, and it's often not at all obvious what has been registered with atexit(). Let the parent process worry about its resources; the child basically owns nothing other than its stack frame!

Donal Fellows