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