Is there a way to start a child process without fork()
, using execvp()
exclusively?
The pedantic answer to your question is no. The only system call that creates a new process is fork
. The system call underlying execvp
(called execve
) loads a new program into an existing process, which is a different thing.
Some species of Unix have additional system calls besides fork
(e.g. vfork
, rfork
, clone
) that create a new process, but they are only small variations on fork
itself, and none of them are part of the POSIX standard that specifies the functionality you can count on on anything that calls itself a Unix.
The slightly more helpful answer is that you might be looking for posix_spawn
, which is a library routine wrapping fork
and exec
into a single operation, but I find it more troublesome to use that correctly than to write my own fork
+exec
subroutine. YMMV.
posix_spawn
might be using a newer fork-with-options primitive, whatever that's called, rather than the original fork(2), but it's still a library routine that wraps a fork operation and an exec operation. Its algorithm has not changed. –
Genova posix_spawn is the only posix compliant way to create a child process without calling fork
directly. I say 'directly' because historically posix_spawn
would itself just call fork
, or vfork
. However, that is no longer the case in GNU/linux. posix_spawn
itself may be more efficient than fork
, in addition to perhaps being a stronger fit conceptually when code is attempting to run a different executable.
If you aren't worried about portability, you can abandon posix and couple yourself directly to the kernel you are targeting. On linux the system call to create a child process is clone. At the time of this answer the manual page provides documentation for three variants, including the relatively new clone3
.
I believe you can take the example from the manual page and add an execvp
call to childFunc
. I have not tried it yet, though!
posix_spawn
itself may be more efficient than fork
The reason is fork()
is broken in glibc and glibc maintainers have been waging a decade-and-a-half effort to get fork()
removed from the POSIX list of async-signal-safe functions. –
Intersidereal Unlike Windows systems, where creating a new process and executing a new process image happen in a single step, Linux and other UNIX-like systems do them as two distinct steps.
The fork
function makes an exact duplicate of the calling process and actually returns twice, once to the parent process and once to the child process. The execvp
function (and other functions in the exec
family) executes a new process image in the same process, overwriting the existing process image.
You can call execvp
without calling fork
first. If so, that just means the currently running program goes away and is replaced with the given program. However, fork
is the way to create a new process.
As user zwol has already explained, execve()
does not fork a new process. Rather, it replaces the address space and CPU state of current process,
loads the new address space from the executable filename and starts it from
main()
with argument list argv
and environment variable list envp
.
It keeps pid and open files.
int execve(const char *filename,char *const argv [],char *const envp[]);
filename
: name of executable file to run
argv
: Command line arguments
envp
: environment variable settings (e.g., $PATH
, $HOME
, etc.)
posix_spawn. But it ignores failures of execvp() -- potentially because implementing this was regarded as too complicated.
© 2022 - 2024 — McMap. All rights reserved.
execvp
is usingfork
orclone
... This question makes no sense without rationale provided. – Avertinexecvp
replaces your process with another executable so hardly a child process. Why the resistance tofork
? – Minhminhofork
then you are not supposed to create a child process, that's it. Or maybe they want you to useclone
. – Avertinexecvp
only! – Ferreirafork
, but it's also possible that you misunderstood the assignment. – Genova