Split from - http://www.daniweb.com/forums/thread47395.html
Ok, here's the solution.
When you have a pipe open in parent process, you have to close the pipe before waiting. It has to do with the file descriptor counters of the pipe ends, they have to be zeroes to not cause a child to block on them (in particular, the read end). The counters are the key if you want to look for more information.
I know that this question has been answered some time ago, but maybe the orignal poster or someone else can give some more explanation on the solution? I'm currently running into the same problem and I don't have a clue what the problem might be. I think we all agree that the error message is not of much use, because I call the waitpid-function as follows:
waitpid(my_pid, &retval, 0)
So as I don't use any options there cannot be an invalid options argument, right? I am actually also using pipes, but I think I'm closing all of the pipe related file descriptors conscientiously that are used for communication with the child to be waited for. I'm also getting the same error message if I use wait instead of waitpid. Does someone have a more general explanation on what the problem might be, when the wait-funciton returns with an error-code set to EINVAL, but the options seem to be set correct?
I'm calling this function in a signal handler that is registered for SIGCHLD. The read part of the pipe to the child has already been closed directly after forking the child. The pid that is used in the waitpid-call also seems to be correct.
void childSignalHandler(int sig, siginfo_t *signal_info, void *context)
{
int slave_id;
int child_exit_status = 0;
for (slave_id = 1; slave_id < MAX_NUM_CLIENTS; slave_id++) {
if (slave_control_struct[slave_id].pid == signal_info->si_pid) {
if (close(slave_control_struct[slave_id].master_channel[1])) {
perror("[INTERNAL] Error while closing write part of pipe");
}
if (waitpid(slave_control_struct[slave_id].pid, &child_exit_status, 0)) {
perror("[INTERNAL] Terminating child");
}
unsubscribeServerSlave(slave_id);
break;
}
}
}