WIFSIGNALED、WIFSTOPPED、WIFCONTINUEDためのCのテストケース
質問
私はのwaitpid()と信号(一緒に遊んだ)と私はWIFSIGNALED(ステータス)= WIFSTOPPED(ステータス)= WIFCONTINUED(ステータス)が真=が、いずれも見つけることができませんを返すために信頼性の高いテストケースを探しています。..ます。
私は自分のコードをデバッグすることができますので、それらがtrueを返すことを確認することができますどのように私に言うように注意?
また、信号は、私が参考になるものをマクロをテストするための信号()でキャッチすべきかについていくつかのヒント...
解決
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#define NELEMS(x) (sizeof (x) / sizeof (x)[0])
static void testsignaled(void) {
kill(getpid(), SIGINT);
}
static void teststopped(void) {
kill(getpid(), SIGSTOP);
}
static void testcontinued(void) {
kill(getpid(), SIGSTOP);
/* Busy-work to keep us from exiting before the parent waits.
* This is a race.
*/
alarm(1);
while(1) {}
}
int main(void) {
void (*test[])(void) = {testsignaled, teststopped, testcontinued};
pid_t pid[NELEMS(test)];
int i, status;
for(i = 0; i < sizeof test / sizeof test[0]; ++i) {
pid[i] = fork();
if(0 == pid[i]) {
test[i]();
return 0;
}
}
/* Pause to let the child processes to do their thing.
* This is a race.
*/
sleep(1);
/* Observe the stoppage of the third process and continue it. */
wait4(pid[2], &status, WUNTRACED, 0);
kill(pid[2], SIGCONT);
/* Wait for the child processes. */
for(i = 0; i < NELEMS(test); ++i) {
wait4(pid[i], &status, WCONTINUED | WUNTRACED, 0);
printf("%d%s%s%s\n", i, WIFCONTINUED(status) ? " CONTINUED" : "", WIFSIGNALED(status) ? " SIGNALED" : "", WIFSTOPPED(status) ? " STOPPED" : "");
}
return 0;
}
他のヒント
取り扱いはWIFSIGNALED簡単です。子プロセスはkill()
システムコールで自殺することができます。また、ダンプコアに確認することができます - いくつかの信号は、それら(SIGQUIT、IIRC)を作成します。いくつかの信号がない(SIGINT)。
取り扱いWIFSTOPPEDは難しいかもしれません。子供が再びkill()
システムコールでそれ自体がSIGSTOPを送信するためにしようとするための簡単なステップがあります。実は、私はそれが動作するはずだと思います。あなたがSIGTTINおよびSIGTTOUやSIGTSTOPに確認したいことがあります - 私は、彼らがWIFSTOPPEDカウントと信じています。 (それは非POSIXシステムコール、ptrace()
を経由して実行されているプロセスにデバッガによって送信されたときにSIGSTOPだけsanely働く可能性もあります。)
取り扱いWIFCONTINUEDは、私は親が関係していると思うものです。あなたは、プロセスが停止された検出した後、あなたの呼び出し元のコードでは、それはそれをSIGCONT信号(再びkill()
)を送信することにより、継続すべきです。子供はこの自体を配信することはできません。それが停止されています。繰り返しますが、私は心配する余分なしわがあるかどうかわからない - 。おそらく
以下のようなフレームワークの何かが、あなたがwait()
とwaitpid()
呼び出しの結果を確認できるようになります。
pid_t pid = fork();
if (pid == 0) {
/* child */
sleep(200);
}
else {
/* parent */
kill(pid, SIGSTOP);
/* do wait(), waitpid() stuff */
}
あなたが実際に送信されます(signal()
または関連機能を使用して)信号をキャッチする必要はありません。 signal()
は、特定のシグナルのデフォルトの動作をオーバーライドするハンドラをインストールする - ので、あなたのプロセスを終了する信号をチェックしたい場合は、そのデフォルトの動作を持っているものを選ぶ - 「man -s7 signal
は」あなたは信号のデフォルトの動作の詳細を与えるだろう。
あなたがSIGSTOP
のために使用WIFSTOPPED(status)
を言及しているマクロについては、SIGCONT
ためWIFCONTINUED (status)
とSIGINT
ためWIFSIGNALED(status)
、あなたのプロセスにシグナルを送信するために(「man kill
」を参照)キルを使用することができます。 kill -l
を送ることができるすべての信号の一覧を表示します。
あなたのテストで、あなたはフォークすることができます()と自分の子プロセスに特定の信号を送信しますか?このシナリオでは、あなたの子プロセスは、テストケースはありますか。
編集
私の答えはCのテストをコーディングについてです。あなたはフォーク、あなたの子プロセスのPIDを取得する(工程
)シグナルハンドラがインストールされて、あなたはkill(2)
を使用して、それに信号を送ることができます。
この方法では、終了ステータスをテストすることができます。