【问题标题】:Why I can't receive SIGPOLL signal from ioctl function?为什么我无法从 ioctl 函数接收到 SIGPOLL 信号?
【发布时间】:2017-07-28 12:44:00
【问题描述】:

我遇到了一个我无法解决的奇怪问题。这是我的代码。

#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。

【问题讨论】:

  • 我怀疑你是否可以在信号处理程序中调用getchar
  • 你不是要在 ioctl 中用不同的值覆盖 SIGPOLL 以获得 '0' 吗?
  • @ZangMingJie 感谢您的建议,这只是一个测试程序。
  • @Serge 谢谢,我试过 SIGIO,但没用。

标签: c linux io signals


【解决方案1】:

在 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,它允许接收您选择的信号并将额外信息接收到信号处理程序中。

【讨论】:

  • 感谢您的建议,它实际上在我的电脑上工作。它解决了我的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多