Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`waitpid()' always returns -1

I'm executing the code below and the call to waitpid() always returns -1, thus the code bellow ends with an infinite loop. The call works if I replace WNOHANG with 0.

void execute(cmdLine* pCmdLine) {
    int status = 0;
    pid_t pid = fork();
    if(pid == 0) {
         if(execvp(pCmdLine->arguments[0], pCmdLine->arguments) == -1) {
             if(strcmp(pCmdLine->arguments[0], "cd") != 0) {
               perror("execute failed\n");
             }
        _exit(1);
        }
    } else {
        if(pCmdLine->blocking == 1) {
            waitpid(pid, &status, 0);
        }
            while(waitpid(pid, &status, WNOHANG) == -1) {
             printf("still -1\n");
            }
         }     
    }
}
like image 878
Liavba Avatar asked Aug 06 '26 07:08

Liavba


1 Answers

Here

 while(waitpid(pid,&status,WNOHANG)==-1) { }

when if there is no more child process exists then waitpid returns -1 and it makes while(true) always and that cause infinite loop.

From the manual page of waitpid().

waitpid(): on success, returns the process ID of the child whose state has changed; if WNOHANG was specified and one or more child(ren) specified by pid exist, but have not yet changed state, then 0 is returned. On error, -1 is returned.

That means, when there are no more child to wait for, it returns -1. So either make it like

if() { /* child process. can be multiple */
} 
else { /* parent process */
    while(waitpid(pid,&status,WNOHANG) != -1) { /* when there is no more child process exists then it terminate */ 
    }
}

or

if() { /* child process. can be multiple */
} 
else { /* parent process */
  while(waitpid(pid,&status,WNOHANG) == -1);  /* dummy while ..when there is no more child process exists then it terminate */ 
}
like image 192
Achal Avatar answered Aug 09 '26 00:08

Achal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!