2017-12-01 7 views
1

POSIX specificationによれば、tcsetpgrpは、バックグラウンドプロセスであれば、呼び出しプロセスのグループにSIGTTOUを送ることができます。呼び出し元がバックグラウンドプロセスに属している場合、tcsetpgrp()は成功しますか?

しかし、そのような場合はフォアグラウンドグループが変更されているかどうかわかりません。

また、シグナル生成にもかかわらずフォアグラウンドグループが実際に変更された場合、新しいフォアグラウンドグループがSIGTTOUを受信するグループであれば、セッションと端末には何が起こるのだろうかと思います。

答えて

1

TL:DR:

ませんフォアグラウンドグループは変更されません。これは、プロセスが端末の設定を変更しているときにシグナルが送信されることになっているので意味があります。変更が成功した場合、シグナルはプロセス(現在はフォアグラウンド・グループ)にも渡されません。なぜなら、誰かがSIGCONTを送信しなくてもそれが詰まる可能性があるからです。

長い答え:

簡単な例:このコードはバックグラウンドプロセスとして起動され、SIGTTOUを扱う場合

#include <unistd.h> 
#include <errno.h> 
#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <signal.h> 


void sig(int signo) { 
    const char* msg = strsignal(signo); // XXX: Not async-signal-safe. 
    write(STDOUT_FILENO, msg, strlen(msg)); 
    write(STDOUT_FILENO, "\n", 1); 
} 

int main() { 
    char cntl_tty[L_ctermid]; 
    ctermid(cntl_tty); 

    signal(SIGTTOU, sig); 
    signal(SIGCONT, sig); 

    int fd = open(cntl_tty, O_RDONLY); 
    if (fd == -1) { 
     perror("open"); 
     exit(1); 
    } 
    if (tcsetpgrp(fd, getpgrp()) == -1) { 
     perror("tcsetpgrp"); 
    } else { 
     puts("foregrounded"); 
    } 
    return 0; 
} 

、これは、信号が受信されることを印刷する永久ループ。 perrorは決して呼び出されません。つまり、カーネルがシステムコールを再起動します。送信SIGCONTは問題ではありません。前向きなことは決して成功しません。しかし、シェルを介してコードをフォアグラウンドにすると、「フォアグラウンド」が期待どおりに出力されます。

SIGTTOUの信号配置をSIG_IGNに変更すると、すぐに「フォアグラウンド」が印刷されます。

+1

私はシグナルハンドラを印刷するだけなので、perrorに到達していないのだろうかと思っています。バックグラウンドプロセスからのすべての印刷がハンドラを再起動させるSIGTTOUを生成した後、もう一度印刷すると、新しいサイトトゥが無限ループに陥る。 –

+0

良い点、私はそれを考えなかった。私はもう一度試して、プリントを取り除いて、空のシグナルハンドラ本体を残して、その振る舞いは変わりません。私はEINTRと思って失敗していたはずだから、プリントがまったく起こったのは奇妙なことです。 –

+0

D'oh、それは "Stopped(tty output)"と書かれたシェルです。 =) –

関連する問題