Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

waitid() error: invalid argument

Tags:

c

linux

I have this code from APUE book and exercise in which I need to replace wait() with waitid():

#include "apue.h"
#include <sys/wait.h>

int main(void)
{
    pid_t   pid;
    int     status;

    if ((pid = fork()) < 0)
        err_sys("fork error");
    else if (pid == 0)              /* child */
        exit(7);

    if (wait(&status) != pid)       /* wait for child */
        err_sys("wait error");
    pr_exit(status);                /* and print its status */

    if ((pid = fork()) < 0)
        err_sys("fork error");
    else if (pid == 0)              /* child */
        abort();                    /* generates SIGABRT */

    if (wait(&status) != pid)       /* wait for child */
        err_sys("wait error");
    pr_exit(status);                /* and print its status */

    if ((pid = fork()) < 0)
        err_sys("fork error");
    else if (pid == 0)              /* child */
        status /= 0;                /* divide by 0 generates SIGFPE */

    if (wait(&status) != pid)       /* wait for child */
        err_sys("wait error");
    pr_exit(status);                /* and print its status */

    exit(0);
}

I tried this:

id_t    pid;
siginfo_t info;
pid = fork();
// ...

waitid(P_PID, pid, &info, WNOHANG) // also tried with WNOWAIT

and got waitid error: Invalid argument. When I tried: waitid(P_PID, pid, &info, WEXITED) I got Signal number: 17 for all three waitid() calls where original code's output are signals 7, 6 and 8 respectively. Why am I getting "invalid argument" and how can I force system to generate signals 7, 6 and 8?

like image 833
Bade Avatar asked Nov 01 '22 04:11

Bade


1 Answers

waitid(P_ALL, 0, &info, WEXITED), where info is of type siginfo_t, collects the same child processes as wait(&status) does. They differ in

  1. the siginfo_t * argument of waitid() and its interpretation vs. the int * argument of wait() and its interpretation, and
  2. the meaning of the two functions' return values.

You appear to want to use waitid() to wait for a particular child each time, however, and that would be this: waitid(P_PID, pid, &info, WEXITED).

Note that whereas wait() returns the pid of the child process it collected on success, waitid() returns 0 on success.

Note also that although the siginfo_t structure has a member named si_status, it is not equivalent to the value wait() provides to the caller via its second argument. siginfo_t.si_status is the process's actual exit code, whereas the status provided by wait() is a bitmask of several different fields. You get the exit code from the latter via the WEXITSTATUS() macro, though you would be wise to check whether it in fact terminated normally (WIFEXITED()) vs. being signaled (WIFSIGNALED()).

like image 164
John Bollinger Avatar answered Nov 15 '22 07:11

John Bollinger