2

実行中のフォアグラウンドプロセスにCTRL-Z(SIGTSTP)ハンドラーをインストールしようとしています。

親のsigaction直前にハンドラー()を設定しました。waitこれは正しい場所ですか?正しく機能していないようです。

編集:

私はシェルを書いています。これが私のコードがどのように見えるかの概要です。私は現在、以下に示すように親にハンドラーを設定しています(これは機能していないようです)。

// input from user for command to run
pid_t pid;
pid = fork();

// Child Process
if (pid == 0) {
    // handle child stuff here
    // exec() etc...
}

else if (pid < 0)
    // error stuff

/* Parent Here */
else {
    // Give process terminal access
    // SET HANDLER FOR SIGTSTP HERE???
    wait()
    // Restore terminal access
}
4

2 に答える 2

3

あなたは物事を完全に間違ってやっています。

SIGTSTPを子プロセスに送信しないでください。ttyはSIGTSTPを子プロセスに直接送信します。

試す

$ stty -a
speed 38400 baud; rows 55; columns 204; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

知らせ:

susp = ^Z;

これは、ttyに「CTRL-Z」の処理方法を指示します。ttyが^ Zを取得すると、現在のフォアグラウンドプロセスグループ内のすべてのプロセスにSIGTSTPシグナルを送信します。

プロセスグループの処理方法

シェルで新しいプロセスを起動するときは、前execvXに、新しいプロセスを新しいプロセスグループに入れてから、を呼び出しtcsetpgrpて新しいプロセスグループをフォアグラウンドに設定します。したがって、将来のシグナルは子プロセスに直接送信されます。子が新しいプロセスをフォークする場合、それらは同じプロセスグループに属します。したがって、^ Zを押すと、プロセスグループ全体が一時停止されます。

pid = fork()
if (pid) {
  // parent
  setpgid(pid, pid); // put child into a new process group
  int status;
  wait(pid, &status, 0);
} else {
  // child
  pid = getpid();
  setpgid(pid, pid);
  if (isatty(0)) tcsetpgrp(0, pid);
  if (isatty(1)) tcsetpgrp(1, pid);
  if (isatty(2)) tcsetpgrp(2, pid);
  execvX ...
}

ttyからシグナルが発生し、子プロセスが停止/終了/終了すると、シェルが元に戻りますwait。ステータスを確認して、子に何が起こったかを確認してください。

シェルが停止しないようにする

シェルはサスペンドしないため、シェルはSIGTSTPシグナルをマスクする必要があります。これは、シェルを開始するときに最初に行います。ただし、forkはsigmaskを派生させることを忘れないでください。そのため、子プロセスでforkの後にSIGTSTPを有効にする必要があります。

于 2012-03-24T19:31:07.057 に答える
0

子を処理するSIGTSTPには、次の後に必要になりwaitpidます。

if (WIFSTOPPED(status)) {
    printf("Child received SIGTSTP");
}
于 2012-03-25T14:01:31.427 に答える