order of SIGCONT and SIGHUP sent to orphaned linux

2020-04-21 07:32发布

问题:

APUE says

Since the process group is orphaned when the parentterminates, POSIX.1 requires that every process in the newly orphaned process group that is stopped (as our child is) be sent the hang-up signal (SIGHUP) followed by the continue signal (SIGCONT)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#define errexit(msg) do{ perror(msg); exit(EXIT_FAILURE); } while(0)
static void sig_hup(int signo)
{
    printf("SIGHUP received, pid = %d\n", getpid());
}
static void sig_cont(int signo)
{
    printf("SIGCONT received, pid = %d\n", getpid());
}
static void sig_ttin(int signo)
{
    printf("SIGTTIN received, pid = %d\n", getpid());
}
static void pr_ids(char *name)
{
    printf("%s: pid = %d, ppid = %d, pgrp = %d, tpgrp = %d\n",
           name, getpid(), getppid(), getpgrp(), tcgetpgrp(STDIN_FILENO));
}
int main(int argc, char *argv[])
{
    char c;
    pid_t pid;
    setbuf(stdout, NULL);
    pr_ids("parent");
    if ((pid = fork()) < 0) {
            errexit("fork error");
    } else if (pid > 0) { /* parent */
            sleep(5);
            printf("parent exit\n");
            exit(0);
    } else { /* child */
            pr_ids("child...1");
            signal(SIGCONT, sig_cont);
            signal(SIGHUP, sig_hup);
            signal(SIGTTIN, sig_ttin);
            kill(getpid(), SIGTSTP);
            //sleep(10);
            pr_ids("child...2");
            if (read(STDIN_FILENO, &c, 1) != 1) {
                    printf("read error from controlling TTY, errno = %d\n", 
                                                             errno);
            }
            printf("child exit\n");
    }
    exit(0);
  }

program output:

parent: pid = 2036, ppid = 1959, pgrp = 2036, tpgrp = 2036
child...1: pid = 2037, ppid = 2036, pgrp = 2036, tpgrp = 2036
parent exit
xiejingfeng@xiejingfeng-desktop:/codes/apue$ SIGCONT received, pid = 2037
SIGHUP received, pid = 2037
child...2: pid = 2037, ppid = 1, pgrp = 2036, tpgrp = 1959
read error from controlling TTY, errno = 5
child exit

output is not expected as what the book says because the program receive SIGCONT firstly then SIGHUP, which is very confusing for me, can you guys help me out?

thanks in advance.

回答1:

The SIGHUP cannot be delivered until the child's execution is resumed. When a process is stopped, all signal delivery is suspended except for SIGCONT and SIGKILL.

So, the SIGHUP does arrive first, but it cannot be processed until the SIGCONT awakens the process execution.