假设此程序在后台运行。
假设包括标题,例如signal.h ......
void SignalHandler(int sig);
int fd;
int main(int argc, char *argv[]){
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);
}
while (1) {
err = read(fd, strbuf, 256);
if(err)
syslog(LOG_INFO,"%s",strbuf);
}
close(fd);
}
void SignalHandler(int sig){
if(fd!=-1)
close(fd);
exit(0);
}
假设此代码已在运行。并且具有testsignal的程序名称。当我在终端再次运行时./testsignal&amp;该过程只是不断加起来...当前正在运行的进程应该退出,新进程应该替换旧进程。所以只有进程应该运行。我需要帮助。感谢
答案 0 :(得分:0)
此代码是对您的简化,因为它不使用syslog()
。它也不会关闭标准输入,标准输出和标准错误,因此守护程序仍然可以将信息记录到标准输出(特别是)。这使我更容易测试。
flprintf()
函数用于确保刷新标准输出的所有输出;它减少了程序中无聊的4行代码块的数量。该程序还记录了更多的活动,这也使得更容易看到正在发生的事情。 (部分原因是因为我设法忽略了注释掉的close()
系统调用。)我创建了一些不必在此源文件静态之外可见的内容;这意味着只有main()
不是静态的。此代码还确保字符串读取为空终止,因此长字符串后跟短字符串不会产生短消息的短消息以及较长字符串的剩余消息。
#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);
}
我在Mac OS X 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
$