waitpid等待子进程收到STOP CONTINU信号,并且从terminal status看是什么信号引起的

来源:互联网 发布:完善网络问政的对策 编辑:程序博客网 时间:2024/06/11 21:08

1. waitpid一般等待子进程的退出,但是也可以用来等待子进程收到的STOP/CONTINU信号

2. 子进程因为什么推出,可以从第二个参数terminal status中查看

 

其中函数pr_exit是用来判断子进程退出原因的。

先是子进程给自己发送了SIGTSTP,这样子进程就停止了。

当父进程收到子进程STP后,发送了SIGCONT信号,让子进程继续执行。

要接收这两个时间,waitpid需要使用WUNTRACED,WCONTINUED这两个option。

 

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

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
 
void pr_exit(int status)
{
    if (WIFEXITED(status))
        printf("normal termination, exit status = %d/n",
                WEXITSTATUS(status));
    else if (WIFSIGNALED(status))
        printf("abnormal termination, signal number = %d%s/n",
                WTERMSIG(status),
#ifdef  WCOREDUMP
                WCOREDUMP(status) ? " (core file generated)" : "");
#else
                "");
#endif
    else if (WIFSTOPPED(status))
        printf("child stopped, signal number = %d/n",
                WSTOPSIG(status));
    else if (WIFCONTINUED(status))
        printf("child continuing.../n");
}

static void sig_hup(int signo)
{
    printf("SIGHUP received, pid = %d/n", getpid());
}

static void sig_tstp(int signo)
{
    printf("SIGTSTP 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));
    fflush(stdout);
}

int main(void)
{
    char   c;
    pid_t  pid;
    int    status;

    pr_ids("parent");
    if ((pid = fork()) < 0)
    {
        perror("fork error");
        return 0;
    }
    else if (pid > 0)
    {
//        sleep(10);
        printf("child process starts %d/n", pid);
        waitpid(pid, &status, WUNTRACED|WCONTINUED);
        pr_exit(status);
        kill(pid, SIGCONT);
        waitpid(pid, &status, WUNTRACED|WCONTINUED);
        pr_exit(status);
        exit(0);
    }
    else
    {
        sleep(5);
        pr_ids("child 1");
//        signal(SIGHUP, sig_hup);
//        signal(SIGTSTP, sig_tstp);
        kill(getpid(), SIGTSTP);
        pr_ids("child 2");
        sleep(10);
        if (read(STDIN_FILENO, &c, 1) != 1)
            printf("read error from controlling TTY, errno = %d/n", errno);
        printf("input: %c/n",c);
        exit(0);
    }

    return 0;
}