博客 / 詳情

返回

SIGTTIN/SIGTTOU 信號

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

補充: 上面的代碼中,在進程中設置了忽略SIGTTOU信號。
因為在tcsetpgrp 的手冊中是這樣説的:如果tcsetpgrp 被一個後端進程組中的一員調用,並且調用進程沒有阻塞或忽略 SIGTTOU,那麼SIGTTOU 信號會被髮送給這個後端進組的所有成員。

我們在在子進程fork一個進程實驗一下如果tcsetpgrp。
實驗一:將上述程序的 signal(SIGTTOU,SIG_IGN); 改為 signal(SIGTTOU,handler); 執行打印結果: 一直在發送SIGTTOU信號,在收到中斷信號後,標記執行tcsetpgrp 失敗。
1660824526462.png

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.