cgcccompiler-errorssigchld

error: conflicting types for ‘wstat’ in gcc


I copied this program from this documentation: https://docs.oracle.com/cd/E19455-01/806-4750/signals-7/index.html

#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/resource.h>

void proc_exit()
{
        int wstat;
        union wait wstat;
        pid_t   pid;

        while (TRUE) {
            pid = wait3 (&wstat, WNOHANG, (struct rusage *)NULL );
            if (pid == 0)
                return;
            else if (pid == -1)
                return;
            else
                printf ("Return code: %d\n", wstat.w_retcode);
        }
}
main ()
{
        signal (SIGCHLD, proc_exit);
        switch (fork()) {
            case -1:
                perror ("main: fork");
                exit (0);
            case 0:
                printf ("I'm alive (temporarily)\n");
                exit (rand());
            default:
                pause();
        }
}

When I run gcc main.c I get this error:

main.c: In function ‘proc_exit’:
main.c:9:13: error: conflicting types for ‘wstat’
  union wait wstat;
             ^~~~~
main.c:8:6: note: previous declaration of ‘wstat’ was here
  int wstat;
      ^~~~~
main.c:9:13: error: storage size of ‘wstat’ isn’t known
  union wait wstat;
             ^~~~~
main.c:12:9: error: ‘TRUE’ undeclared (first use in this function)
  while (TRUE) {

As I understand wstat is defined twice. Does it mean that documentation is incorrect? And how it can be fixed?


Solution

  • Yeah, that code is just broken. I don't know what the intention was with the union wait wstat;. Maybe some copy paste error from the documentation author. Who knows. The code in general is written quite poorly, IMO.

    Anyway, here's what the code is actually trying to do:

    int wstat;
    pid_t pid;
    
    while (1) {
        pid = wait3(&wstat, WNOHANG, NULL);
        if (pid == 0 || pid == -1)
            return;
        printf("Return code: %d\n", wstat);
    }