乐趣区

关于unix:SIGTTINSIGTTOU-信号

SIGTTIN: 当一个后盾过程组试图读取其管制终端时,终端驱动程序产生此信号。在下列例外情况不产生次信号:a、读过程疏忽或者梗塞此信号 b、读过程所属的过程组是孤儿过程组,此时读操作返回出错,errno 设置未 EIO。

SIGTTOU: 当一个后盾过程组试图写其管制终端时,终端驱动程序产生此信号。与 SIGTTIN 信号不同,一个过程能够算着容许后盾过程写管制终端。如果不容许写管制终端,则与 SIGTTIN 类似,也有两种非凡状况:a、写过程疏忽或者梗塞此信号 b:写过程所属的过程组是孤儿过程组,此时读操作返回出错,errno 设置未 EIO。

SIGTTIN 和 SIGTTOU 信号的默认动作是暂停过程。

下图代码,过程启动,fork 出子过程,子过程设置过程组,调用 tcsetpgrp 将本人设置为前端过程组,父过程就变成了后端过程组。在 read 的时候,暂停。

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

// 打印过程信息
void pr_process(char * name){printf("%s  pid:%d,ppid:%d,pgid:%d,sid:%d,grrp:%d\n",name,getpid(),getppid(),getpgid(getpid()),getsid(getpid()),tcgetpgrp(STDIN_FILENO));
}

void handler(int sig){printf("receive %d sig\n",sig);
}

int main(int argc,char *argv[]){
        pid_t pid ;

        pid_t fpgid = tcgetpgrp(STDIN_FILENO);
        if((pid = fork()) < 0){perror("fork error");
                exit(1);
        }

        if(pid == 0){signal(SIGTTOU,SIG_IGN);
                setpgid(getpid(),getpid());
                pr_process("child before set:");
                if(tcsetpgrp(STDIN_FILENO,getpid()) == -1){printf("set error\n");
                        exit(2);
                }
                pr_process("child after set");
                exit(1);

        }

        pr_process("parent1");
    waitpid(pid,NULL,0);
        pr_process("parent2");
        char buf[100];
//    signal(SIGTTIN,handler);
        if(read(STDIN_FILENO,buf,100) < 0){perror("read error");
                printf("error\n");
                exit(127);
        }
        printf("sucess\n");
        return 0;
}
退出移动版