このコードは、を使用しないという点であなたのコードを単純化したものですsyslog()
。また、標準入力、標準出力、および標準エラーを閉じないため、デーモンには、情報を標準出力に(具体的には)ログに記録する方法があります。これにより、テストが簡単になります。
このflprintf()
関数は、標準出力へのすべての出力が確実にフラッシュされるようにするために使用されます。プログラム内の退屈な4行のコードブロックの数を減らします。プログラムはまた、そのアクティビティの多くをログに記録します。これにより、何が起こっているのかを簡単に確認できます。(これは、コメントアウトされたclose()
システムコールを見落とすことができたためです。)このソースファイルの外部に表示する必要のないものはすべて静的にします。つまり、main()
静的ではないということです。このコードは、読み取られた文字列がnullで終了することも保証するため、長い文字列の後に短い文字列が続く場合、短い文字列と長い文字列の残りの部分が混ざり合ったメッセージは生成されません。
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdarg.h>
static void flprintf(const char *fmt, ...);
static void SignalHandler(int sig);
static int fd = -1;
int main(int argc, char **argv)
{
int nbytes;
char strbuf[257];
if (argc > 1)
{
int pid = atoi(argv[1]);
if (kill(pid, SIGINT) != 0)
flprintf("Failed to deliver SIGINT to PID %d\n", pid);
else
flprintf("SIGINT successfully delivered to PID %d\n", pid);
}
flprintf("Starting - %d\n", (int)getpid());
signal(SIGINT, SignalHandler);
signal(SIGHUP, SignalHandler);
signal(SIGTERM, SignalHandler);
setsid();
//close(0);
//close(1);
//close(2);
fd = open("./myPIPE", O_RDWR);
if (fd < 0)
{
perror("open() error");
exit(1);
}
flprintf("Starting read loop\n");
while ((nbytes = read(fd, strbuf, sizeof(strbuf)-1)) > 0)
{
strbuf[nbytes] = '\0';
flprintf("<<%s>>\n", strbuf);
}
flprintf("Read EOF - %d exiting\n", (int)getpid());
close(fd);
return(0);
}
void SignalHandler(int sig)
{
flprintf("Received signal %d - %d exiting\n", sig, (int)getpid());
if (fd != -1)
close(fd);
exit(0);
}
static void flprintf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
fflush(stdout);
}
私はMacOSX 10.7.5でテストしました(GCC 4.7.1、この場合はそれほど重要ではありません)。動作中に驚いた唯一の動作は、FIFOにメッセージを書き込むプロセスが閉じたときにプログラムがEOFを取得しなかったことです。O_RDWR
しかし、それはopen()
電話で説明されていると思います。FIFOが開いているプロセス(これ)がまだあります。で再コンパイルするO_RDONLY
と、パイプに最初に何かが書き込まれた後にプロセスが終了します...健全性ルール。EOFを報告しないFIFOを実現する方法としては、これまでに行ったことは問題ありません。(プロセスがFIFOを開くのを待って、プロセスがオープンでブロックしなかった理由も説明します。)
サンプル出力:
$ ./sig >> sig.out &
[1] 47598
$ cat sig.out
Starting - 47598
Starting read loop
$ echo "Testing, 1, 2, 3" > myPIPE
$ cat sig.out
Starting - 47598
Starting read loop
<<Testing, 1, 2, 3
>>
$ echo "Another test - 1, 2, 3" > myPIPE
$ echo "Mini test - 1, 2" > myPIPE
$ cat sig.out
Starting - 47598
Starting read loop
<<Testing, 1, 2, 3
>>
<<Another test - 1, 2, 3
>>
<<Mini test - 1, 2
>>
$ ./sig 47598 >> sig.out &
[2] 47610
$ cat sig.out
Starting - 47598
Starting read loop
<<Testing, 1, 2, 3
>>
<<Another test - 1, 2, 3
>>
<<Mini test - 1, 2
>>
Received signal 2 - 47598 exiting
SIGINT successfully delivered to PID 47598
Starting - 47610
Starting read loop
[1]- Done ./sig >> sig.out
$ echo "Testing, 1, 2, 3" > myPIPE
$ cat sig.out
Starting - 47598
Starting read loop
<<Testing, 1, 2, 3
>>
<<Another test - 1, 2, 3
>>
<<Mini test - 1, 2
>>
Received signal 2 - 47598 exiting
SIGINT successfully delivered to PID 47598
Starting - 47610
Starting read loop
<<Testing, 1, 2, 3
>>
$ kill 47610
$ cat sig.out
Starting - 47598
Starting read loop
<<Testing, 1, 2, 3
>>
<<Another test - 1, 2, 3
>>
<<Mini test - 1, 2
>>
Received signal 2 - 47598 exiting
SIGINT successfully delivered to PID 47598
Starting - 47610
Starting read loop
<<Testing, 1, 2, 3
>>
Received signal 15 - 47610 exiting
[2]+ Done ./sig 47598 >> sig.out
$