I’m working through example in Advanced Programming in the UNIX Environment:
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
static void
sig_hup(int signo)
{
printf("SIGHUP received, pid = %ld\n", (long)getpid());
}
static void
pr_ids(char *name)
{
printf("%s: pid = %ld, ppid = %ld, pgrp = %ld, tpgrp = %ld\n",
name, (long)getpid(), (long)getppid(), (long)getpgrp(),
(long)tcgetpgrp(STDIN_FILENO));
fflush(stdout);
}
int
main(void)
{
char c;
pid_t pid;
pr_ids("parent");
if ((pid = fork()) < 0) {
exit(1);
} else if (pid > 0) { /* parent */
sleep(5); /* sleep to let child stop itself */
} else { /* child */
pr_ids("child");
signal(SIGHUP, sig_hup); /* establish signal handler */
printf("test\n");
kill(getpid(), SIGTSTP); /* stop ourself */
pr_ids("child"); /* prints only if we're continued */
if (read(STDIN_FILENO, &c, 1) != 1)
printf("read error %d on controlling TTY\n", errno);
}
exit(0);
}
The idea is that:
- We create child process
- It has a handler for SIGHUP
- We stop the child with SIGTSTP
- Parent terminates and child is orphaned (member of orphaned process group)
- POSIX.1 requires that stopped processed should be sent SIGHUP (which we handle) followed by SIGCONT
- This should run the child’s SIGHUP handler and continue process
When running this program from shell, I get flaky results. The example in book show this output:
$ ./a.out
parent: pid = 6099, ppid = 2837, pgrp = 6099, tpgrp = 6099
child: pid = 6100, ppid = 6099, pgrp = 6099, tpgrp = 6099
$ SIGHUP received, pid = 6100
child: pid = 6100, ppid = 1, pgrp = 6099, tpgrp = 2837
read error 5 on controlling TTY
However, my results are:
- either no message that SIGHUP was received
$ ./a.out
parent: pid = 294729, ppid = 291330, pgrp = 294729, tpgrp = 294729
child: pid = 294730, ppid = 294729, pgrp = 294729, tpgrp = 294729
- or SIGHUP was received but child didn’t print it’s pid output (so it didn’t continue correctly)
$ ./a.out
parent: pid = 295709, ppid = 291330, pgrp = 295709, tpgrp = 295709
child: pid = 295710, ppid = 295709, pgrp = 295709, tpgrp = 295709
SIGHUP received, pid = 295710
- or child did print it’s output after SIGCONT, but I didn’t get an error on tty.
$ ./a.out
parent: pid = 294722, ppid = 291330, pgrp = 294722, tpgrp = 294722
child: pid = 294723, ppid = 294722, pgrp = 294722, tpgrp = 294722
SIGHUP received, pid = 294723
child: pid = 294723, ppid = 2065, pgrp = 294722, tpgrp = 294722
I’d like to get an idea on why there is such variance between the results.