C语言&sigintHandler
C language & sigintHandler
突然点击"ctrl+c"想删除FIFO文件。我想捕获该信号,然后在实际终止进程之前删除之后的信号。
这是我的代码,我不知道出了什么问题:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#define MAX_BUF 512
void sigintHandler(int sig_num,char * myfifo)
{
puts("hello you there .please don't leave ");
unlink(myfifo);
exit(0);
}
int main()
{
printf("Access-Control-Allow-Origin: *\n");
printf("Content-Type: text/event-stream\n\n");
int fd;
char buf[MAX_BUF];
char * myfifo = "/tmp/omcipipe";
struct stat st;
//捕捉 ctrl c
sigaction(SIGINT, sigintHandler);
//Create FIFO file
if (stat(myfifo, &st) != 0)
mkfifo(myfifo, 0666);
fd = open(myfifo, O_RDONLY);
while (read(fd, buf, MAX_BUF)>0)
{
printf("data: %s", buf);
printf("\n");
fflush(stdout);
}
puts( "----closing----");
close(fd);
unlink(myfifo);
return 0;
}
首先,您使用 sigaction()
设置信号处理程序的方式不正确,因为您没有填写 struct sigaction
的所有成员。填写所有必填成员
struct sigaction info;
info.sa_handler = sigintHandler;
sigaction(SIGINT,&info,NULL);
其次,从 fifo
文件读取数据 而循环 不需要,因为您一次读取 MAX_BUF
。不需要循环,这样读
int ret = read(fd, buf, MAX_BUF);
buf[ret-1] = '[=11=]'; /*it should be null terminated */
第三,sigintHandler()
只有一个参数除外。来自 sigaction()
的手册页
struct sigaction {
void (*sa_handler)(int); /*handler expects only 1 argument */
/* other member */
}
最后也是最重要的是,从信号处理程序中调用 printf()
和 exit()
等函数是不安全的。
你的 sigHandler()
看起来像
static void sigintHandler(int sig_num) {
write(1,"in isr\n",strlen("in isr\n"));
/* set some flag variable here & use that
flag variable in main() function to remove the fifo */
}
看到这个How to avoid using printf in a signal handler?
这是示例代码
static int fifo_flag = 0;
static void sigintHandler(int sig_num) {
write(1,"in isr\n",strlen("in isr\n"));
fifo_flag = 1;
}
int main(void){
printf("Access-Control-Allow-Origin: *\n");
printf("Content-Type: text/event-stream\n\n");
int fd = 0, index = 0;
char buf[MAX_BUF];
#if 0
char *myfifo = "data";
#endif
//char * myfifo = "/tmp/omcipipe";
struct stat st;
struct sigaction info;
info.sa_handler = sigintHandler;
//info.sa_flags = /* set to defaulgs a/c to your requirement*/
if (stat(myfifo, &st) != 0) {
mkfifo(myfifo, 0666);
perror("mkfifo");
}
fd = open(myfifo, O_RDONLY | 0666);
if(fd == -1){
perror("open");
return 0;
}
char ch = 0;
while(read(fd, &ch, 1) > 0) {
sigaction(SIGINT,&info,NULL);/* if ctrl+c is called */
buf[index] = ch;
//sleep(1);/* just to observe ctrl+c behaviour, not advised to use */
printf("%c\n",buf[index]);
index++;
}
buf[index] = '[=14=]';
printf("data: %s", buf);
printf("\n");
puts( "----closing----");
close(fd);
if(fifo_flag == 1) { /*if flag is set, unlink fifo */
unlink(myfifo); /* you can unlink fifo file here */
}
return 0;
}
你的代码有很多问题。
此代码假定 read()
以 '[=15=]'
字符终止数据:
while (read(fd, buf, MAX_BUF)>0)
{
printf("data: %s", buf);
printf("\n");
fflush(stdout);
}
read()
仅读取原始字节,仅此而已。它不会正确终止带有 '[=15=]'
字符的字符串。所以 printf()
几乎肯定会调用未定义的行为。
这个代码
sigaction(SIGINT, sigintHandler);
完全错了。 sigaction()
takes three parameters:
#include <signal.h>
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
你也只能做出async-signal-safe function calls from within a signal handler。此代码
void sigintHandler(int sig_num,char * myfifo)
{
puts("hello you there .please don't leave ");
unlink(myfifo);
exit(0);
}
调用 puts()
和 exit()
,两者都不是异步信号安全的。
并且如评论中所述,信号处理程序代码假定 myfifo
作为第二个参数传递。它不是。根据 the sigaction man page,第二个参数是 struct siginfo *
,其中包含有关信号上下文的信息 - 但前提是 struct sigaction
传递给注册信号处理程序的 sigaction()
调用具有 SA_SIGINFO
标志集,并且使用 sa_sigaction
成员而不是 sa_handler
成员设置处理程序。
突然点击"ctrl+c"想删除FIFO文件。我想捕获该信号,然后在实际终止进程之前删除之后的信号。 这是我的代码,我不知道出了什么问题:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#define MAX_BUF 512
void sigintHandler(int sig_num,char * myfifo)
{
puts("hello you there .please don't leave ");
unlink(myfifo);
exit(0);
}
int main()
{
printf("Access-Control-Allow-Origin: *\n");
printf("Content-Type: text/event-stream\n\n");
int fd;
char buf[MAX_BUF];
char * myfifo = "/tmp/omcipipe";
struct stat st;
//捕捉 ctrl c
sigaction(SIGINT, sigintHandler);
//Create FIFO file
if (stat(myfifo, &st) != 0)
mkfifo(myfifo, 0666);
fd = open(myfifo, O_RDONLY);
while (read(fd, buf, MAX_BUF)>0)
{
printf("data: %s", buf);
printf("\n");
fflush(stdout);
}
puts( "----closing----");
close(fd);
unlink(myfifo);
return 0;
}
首先,您使用 sigaction()
设置信号处理程序的方式不正确,因为您没有填写 struct sigaction
的所有成员。填写所有必填成员
struct sigaction info;
info.sa_handler = sigintHandler;
sigaction(SIGINT,&info,NULL);
其次,从 fifo
文件读取数据 而循环 不需要,因为您一次读取 MAX_BUF
。不需要循环,这样读
int ret = read(fd, buf, MAX_BUF);
buf[ret-1] = '[=11=]'; /*it should be null terminated */
第三,sigintHandler()
只有一个参数除外。来自 sigaction()
struct sigaction {
void (*sa_handler)(int); /*handler expects only 1 argument */
/* other member */
}
最后也是最重要的是,从信号处理程序中调用 printf()
和 exit()
等函数是不安全的。
你的 sigHandler()
看起来像
static void sigintHandler(int sig_num) {
write(1,"in isr\n",strlen("in isr\n"));
/* set some flag variable here & use that
flag variable in main() function to remove the fifo */
}
看到这个How to avoid using printf in a signal handler?
这是示例代码
static int fifo_flag = 0;
static void sigintHandler(int sig_num) {
write(1,"in isr\n",strlen("in isr\n"));
fifo_flag = 1;
}
int main(void){
printf("Access-Control-Allow-Origin: *\n");
printf("Content-Type: text/event-stream\n\n");
int fd = 0, index = 0;
char buf[MAX_BUF];
#if 0
char *myfifo = "data";
#endif
//char * myfifo = "/tmp/omcipipe";
struct stat st;
struct sigaction info;
info.sa_handler = sigintHandler;
//info.sa_flags = /* set to defaulgs a/c to your requirement*/
if (stat(myfifo, &st) != 0) {
mkfifo(myfifo, 0666);
perror("mkfifo");
}
fd = open(myfifo, O_RDONLY | 0666);
if(fd == -1){
perror("open");
return 0;
}
char ch = 0;
while(read(fd, &ch, 1) > 0) {
sigaction(SIGINT,&info,NULL);/* if ctrl+c is called */
buf[index] = ch;
//sleep(1);/* just to observe ctrl+c behaviour, not advised to use */
printf("%c\n",buf[index]);
index++;
}
buf[index] = '[=14=]';
printf("data: %s", buf);
printf("\n");
puts( "----closing----");
close(fd);
if(fifo_flag == 1) { /*if flag is set, unlink fifo */
unlink(myfifo); /* you can unlink fifo file here */
}
return 0;
}
你的代码有很多问题。
此代码假定 read()
以 '[=15=]'
字符终止数据:
while (read(fd, buf, MAX_BUF)>0)
{
printf("data: %s", buf);
printf("\n");
fflush(stdout);
}
read()
仅读取原始字节,仅此而已。它不会正确终止带有 '[=15=]'
字符的字符串。所以 printf()
几乎肯定会调用未定义的行为。
这个代码
sigaction(SIGINT, sigintHandler);
完全错了。 sigaction()
takes three parameters:
#include <signal.h>
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
你也只能做出async-signal-safe function calls from within a signal handler。此代码
void sigintHandler(int sig_num,char * myfifo)
{
puts("hello you there .please don't leave ");
unlink(myfifo);
exit(0);
}
调用 puts()
和 exit()
,两者都不是异步信号安全的。
并且如评论中所述,信号处理程序代码假定 myfifo
作为第二个参数传递。它不是。根据 the sigaction man page,第二个参数是 struct siginfo *
,其中包含有关信号上下文的信息 - 但前提是 struct sigaction
传递给注册信号处理程序的 sigaction()
调用具有 SA_SIGINFO
标志集,并且使用 sa_sigaction
成员而不是 sa_handler
成员设置处理程序。