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;
	}
    }
}

Recommended Answers

All 2 Replies

if (waitpid(slave_control_struct[slave_id].pid, &child_exit_status, 0)) {

Keep in mind that on success waitpid returns a pid, not zero. Change your code to

if (waitpid(slave_control_struct[slave_id].pid, &child_exit_status, 0) == -1) {

PS: perror is not safe in a signal handler.
PPS: To answer your original question,

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?

errno is only meaningful if the system call actually failed. In your case it succeeded.

PS: perror is not safe in a signal handler.
PPS: To answer your original question, errno is only meaningful if the system call actually failed. In your case it succeeded.

It's embarrassing to oversee the trivial things, but sometimes you're so focused on finding the complicated solution that it's good to have someone else to look at your code.

Thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.