I have three processes, the main process forks a new one and this son process forks another one (the "grandson" process).
I already have a signal handler in the main process that manages the SIGCHLD signals and calls waitpid, but I am not sure if I should use this signal handler also for the "grandson" process or if I should call waitpid for the grandson process in the son process and then use the signal handler to receive the SIGCHLD signal from son process.
It seems that if I create a son process that also creates another process and so on, the first process will receive SIGCHLD signals from all the processes that his sons and grandsons create, is that right?
I have done some tests and it works like that, but there is something I don't understand. In the begining I put both options, the main process' signal handler and the waitpid in the son process. In this case it depends on which process is faster and sometimes is the signal handler in the main process the one who gets the grandson's death and sometimes it is the son process' waitpid call, I show some printfs:

Code:
#####################################
DEBUG: FORK son process PID: 4237			<- main process forks and create a son process (4237)
DEBUG: FORK grandson process PID: 4238			<- son process forks and create a grandson process (4238)
DEBUG: Command executed					<- command execution ends
DEBUG: SIGHANDLER waitpid error: No child processes	<- main process receives a SIGCHLD signal but waitpid fails (no child processes)
DEBUG: WAITPID in son process takes PID: 4238		<- son process' waitpid gets the grandson's death
DEBUG: SIGHANDLER: SIGCHLD PID: 4237			<- main process receives a SIGCHLD and signal_handler's waitpid gets the son's death
#####################################
DEBUG: FORK son process PID: 4275			<- main process forks and create a son process (4275)
DEBUG: FORK grandson process PID: 4276			<- son process forks and create a grandson process (4276)
DEBUG: Command executed					<- command execution ends
DEBUG: SIGHANDLER: SIGCHLD PID: 4276			<- main process receives a SIGCHLD and signal_handler's waitpid gets the grandson's death
DEBUG: WAITPID in son process: No child processes	<- son process' waitpid fails (no child processes)
DEBUG: SIGHANDLER: SIGCHLD PID: 4275			<- main process receives a SIGCHLD and signal_handler's waitpid gets the son's death
That makes sense because if the signal handler picks up the grandson's death before the son's waitpid call, then it will fail because there is no child process to pick up BUT, what I don't understand is why the waitpid call in the son process fails if I disable the SIGCHLD signal in the son process (to prevent the signal handler from getting the end of the grandson process). This are the printfs:

Code:
// if I disable SIGCHLD signals in son process the main process' signal_handler does not receive grandson's SIGCHLD but the waitpid in son process fails
#####################################
DEBUG: FORK son process PID: 4315
DEBUG: FORK grandson process PID: 4316
DEBUG: Command executed
DEBUG: WAITPID in son process: No child processes
DEBUG: SIGHANDLER: SIGCHLD PID: 4315
To disable the SIGCHLD signal in son process I do this:
Code:
signal_action.sa_handler = SIG_IGN;
signal_action.sa_flags   = 0;
sigemptyset(&signal_action.sa_mask);
if (sigaction(SIGCHLD, &signal_action, NULL) != 0){
    if(!daemon_mode) fprintf(stderr, "Error setting SIGCHLD signal handler\n");
}