为什么我无法从ioctl函数接收SIGPOLL信号?
问题描述:
我有一个奇怪的问题,我无法解决。这是我的代码。为什么我无法从ioctl函数接收SIGPOLL信号?
#include <stdio.h>
#include <stropts.h>
#include <signal.h>
#include <sys/types.h>
void handle_signal(int s)
{
char c = getchar();
printf("got char '%c'\n");
if(c == 'q')
{
exit(0);
}
}
int main(int argc, char** argv)
{
sigset(SIGPOLL, handle_signal);
ioctl(0, I_SETSIG, S_RDNORM);
printf("type q to exit");
while(1);
return 0;
}
当我运行这个程序,我在终端键入字符,但它没有工作!我无法收到SIGPOLL信号。有人可以给我一些建议吗?顺便说一下,我的操作系统是Ubuntu 12.04。
答
在Linux上,需要在文件描述符上设置O_ASYNC
标志和F_SETOWN
属性以获得SIGIO
信号(SIGPOLL
的同义词)。和信号处理程序只能调用异步信号安全功能:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <ctype.h>
void handle_signal(int) { // Can only use async-signal safe functions here.
char msg[] = "got char c\n";
char* c = msg + (sizeof msg - 3);
if(1 != read(STDIN_FILENO, c, 1) || !isprint(*c))
return;
write(STDOUT_FILENO, msg, sizeof msg - 1);
if(*c == 'q')
exit(EXIT_SUCCESS);
}
int main() {
printf("type q to exit\n");
signal(SIGIO, handle_signal);
fcntl(STDIN_FILENO, F_SETFL, O_ASYNC | fcntl(STDIN_FILENO, F_GETFL));
fcntl(STDIN_FILENO, F_SETOWN, getpid());
sigset_t mask;
sigemptyset(&mask);
for(;;)
sigsuspend(&mask);
return EXIT_SUCCESS;
}
你可能也想看看F_SETSIG
,以允许收到您的选择和额外信息的信号到信号处理程序。
+0
感谢您的建议,它实际上在我的电脑中工作。它解决了我的问题。 – BrianChen
我怀疑你是否可以在信号处理程序中调用'getchar'。 –
是不是你试图用ioctl中'0'的不同值覆盖SIGPOLL? – Serge
@ZangMingJie谢谢你的建议,它只是一个测试程序。 – BrianChen