Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When I call vfork(), can I call any exec*() function, or must I call execve()?

Tags:

c

linux

exec

vfork

From the Linux man page:

The vfork() function has the same effect as fork(2), except that the behavior is undefined if the process [...] calls any other function before successfully calling [...] one of the exec(3) family of functions.

This suggests that calling any exec*() function after vfork() is acceptable. However, later in the man page it says specifically:

In particular, the programmer cannot rely on the parent remaining blocked until the child [...] calls execve(2) [...].

execve(2) is used repeatedly in the man page, and its usage suggests that it's the only exec-type function that is acceptable after vfork().

So why is execve being singled out here, and am I safe to call other exec-type functions (like execlp)?

like image 878
Cornstalks Avatar asked Jun 14 '14 18:06

Cornstalks


People also ask

What happens when a running process Executive vfork () call?

When vfork() is called in a multithreaded process, only the calling thread is suspended until the child terminates or executes a new program. This means that the child is sharing an address space with other running code.

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?

This leads to more efficient memory usage. Question 7: [6 points] In terms of call-return behavior, how are the fork() and exec() system calls different from other system/function calls? Ans: fork(), if successful, returns twice – once in the parent and once in the child. Exec() never returns, if successful.

Where is Vfork used?

The vfork() function can be used to create new processes without fully copying the address space of the old process. If a forked process is simply going to call exec, the data space copied from the parent to the child by fork() is not used.


1 Answers

You must call execve. There is no guarantee that any of the other exec-family functions do not perform actions which would be unsafe after vfork. For example:

  • execl may allocate memory for the argument list. It's required to be async-signal-safe, which means it's unlikely to use malloc, but even if it doesn't, there's no way it could free the allocated memory (which exists in the parent's memory space) after the underlying execve takes place, so it would (at best) leak memory in the parent unless it manages to construct the argument list on the stack.

  • execvp needs to access the environment to perform a path search, and also needs to construct concatenated pathnames to pass to execve. The latter may require allocation and the former may do all sorts of unsafe-after-vfork things (note: execvp is not even async-signal-safe).

etc.

Really you should simply not use vfork. It's almost impossible to make its use safe. In particular it's unsafe in any program that's using signal handlers since the signal handler could run in the child while it's sharing the parent's memory unless you block all signals (and in that case the child would inherit a fully-blocked signal mask after exec, which is almost surely not what you want).

If you're looking for a more-efficient alternative to fork, use posix_spawn.

like image 157
R.. GitHub STOP HELPING ICE Avatar answered Sep 29 '22 10:09

R.. GitHub STOP HELPING ICE