I started by debugging a weird test failure in ghc. I narrowed it
down to a simple C program which behaves differently between OpenBSD and
FreeBSD. I stared at the headers of both systems for a bit and still
don't see why on OpenBSD the program prints:

uname -a ; cc ./a.c && ./a.out
OpenBSD home.nest.cx 7.0 GENERIC.MP#28 amd64
x 0 pret 130

Yet on FreeBSD:
uname -a ; cc ./a.c && ./a.out
FreeBSD ... 13.0-STABLE FreeBSD 13.0-STABLE
x 0 pret -2

Where's the signed/unsigned confusion hiding?

#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>

#define TERMSIG_EXITSTATUS(s) (-(WTERMSIG(s)))


int
waitForProcess (pid_t handle, int *pret)
{
    int wstat;

    if (waitpid(handle, &wstat, 0) < 0)
    {
        return -1;
    }

    if (WIFEXITED(wstat)) {
        *pret = WEXITSTATUS(wstat);
        return 0;
    }
    else {
        if (WIFSIGNALED(wstat))
        {
            *pret = TERMSIG_EXITSTATUS(wstat);
            return 0;
        }
        else
        {
            /* This should never happen */
        }
    }

    return -1;
}

int main(int a, char**b) {
        pid_t pid = fork();
        if (pid == 0) {
                char* args[4] = {"/bin/sh", "-c", "kill -INT $$", NULL};
                char* env[2] = {NULL};
                int y = execve("/bin/sh", args, env);
                perror("ouch");
                _exit(43);
        }
        int pret = 0;
        int x = waitForProcess(pid, &pret);
        printf("x %d pret %d\n", x, pret);
}

Reply via email to