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