How to use fork() ?


I've been playing with "fork()" recently to run "execv()" and start a new command. The thing is "execv()" replace the process. This means it replace the whole program calling "execv()".

At first, I noticed a lot of new process running at each "fork()". I thought it was zombies process (it wasn't, I just forgot to close a socket), so I dig the topic.

Zombie process are stopped processes, but the OS don't know they have finished. If there are too many, It can be problematic at some point.

Normally, you must call "wait()" or "waitpid()" in the parent process :

const char *cmd[] = { "/usr/bin/top", "-s", "0.5", NULL };
pid_t pid = fork();
if (pid == -1) {
	err(1, "fork");
} else if (pid == 0) {
	/* child */
	execv(cmd[0], (char **)cmd);
	err(1, "execv");
} else {
	/* parent */
	wait(NULL);  // blocking
	/* or : 
	waitpid(pid, NULL, WNOHANG); // non-blocking

However, one may find annoying to add those "wait()" calls.

In order to make sure all forks are waited, you may add a signal before calling "fork()" at the beggining of your main() :

#include <signal.h>

static void sigchld(int unused);

sigchld(int unused)
	(void)unused; // avoid unused variable warning
	while (waitpid(WAIT_ANY, NULL, WNOHANG) > 0);

main(int argc, char *argv[])
	/* ... */
	if (signal(SIGCHLD, sigchld) == SIG_ERR)
		err(1, "can't install SIGCHLD handler:");
	/* ... */

This is something I would have known before (gemini)

This is something I would have known before (http)