fork() and exec() work well as separate system calls
for the common situation where the child (but not the
parent) needs to adjust something before executing
the new program. Changing file descriptors to implement
> and < in the shell, for example. It's common to see
sequences like
Aye. This way, we can control a large number of aspects of the child's environment in which execve() is called, without having to have execve() do all that work for us. We can open files, change the session id, reparent the process to init, alter environment variables, lower process limits, change credentials, change the root directory... the possibilities are legion.
You wouldn't want to have to design a way to pass all of those things to execve(), would you?
New server: one Xeon E5-2690 chip, 2.9 GHz, 8 cores total, 32 GB RAM.