2017-06-14 44 views
0

我在GNU库中发现了记录在SIGU信号中的SIGIO信号。据说只要有输入(特别是套接字),系统就有可能发送信号。 根据创建此类信号的文档,我应该将O_ASYNC标志设置为相应的filedescritor。 我的问题是,我的GNU版本(GCC 6.3.0)不承认这样的关键字:在GNU中设置标准信号SIGIO

error: ‘O_ASYNC’ undeclared (first use in this function)

我用以下块设置一个标志:

/* Set socket status async */ 
int status = fcntl(sockfd, F_SETFL, O_ASYNC);; 
if (status < 0) error("Can't set async mode"); 
else printf("Async is set for signal %d\n", SIGIO); 

我用Cigwin GCC 6.3 0.0

的代码如下:

static void OnTimer(int sig) 
{ 
    /* write request to socket BIO */ 
} 
static void OnTick(int sig) 
{ 
    char read[BUFSIZE] = {}; 
    int received; 

    received = SSL_read(ssl, read, sizeof(read)); 
    /* Handle errors here */ 
    /* print the server's reply */ 
    printf("%s\n\n", read); 
} 

void connectSSL() 
{ 
    /* do all socket set-up and connection */ 

    /* Establish handler for I/O signal */ 
    saction.sa_flags = 0; 
    saction.sa_handler = OnTick; 
    sigemptyset(&saction.sa_mask); 
    sigaddset(&saction.sa_mask, SIGALRM); 
    if (sigaction(SIGIO, &saction, NULL) == -1) error("sigaction"); 
    else printf("OnTick handler created\n"); 

    /* Set socket status async */ 
    int status = fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | FASYNC); 
    if (status < 0) error("Can't set async mode"); 
    else printf("Async is set for signal %d\n", SIGIO); 

    /* Select the process to receive the signal */ 
    int process = fcntl(sockfd, F_SETOWN, getpid()); 
    if (process < 0) error("Can't set address process"); 
    else printf("Process %d is set\n", getpid()); 

    /* do the rest SSL staff here */ 
} 

int main(int argc, char argv[]) 
{ 
    sigset_t mask, oldmask; 
    /* Wait for OnTimer event*/ 
    sigemptyset(&oldmask); 
    sigaddset(&oldmask, SIGALRM); 
    sigemptyset(&mask); 
    sigaddset(&mask, SIGALRM); 
    sigaddset(&mask, SIGIO); 
    sigprocmask(SIG_BLOCK, &mask, &oldmask); 
    connectSSL(); 
    createTimer(500000000); 
    while(1) 
    { 
     printf("\nWaiting OnTimer %d\n", count + 1); 
     sigsuspend(&oldmask); 
    } 

    return 0; 
} 
+0

除了下面我实际的回答:在我的经验信号控制的I/O开辟了更多的问题比它实际上解决。一旦你从一个信号处理程序(你的操作系统查找“异步安全函数”)中知道你实际上可能做了什么*,你可能想要将你的设计恢复为'select'。 – tofro

+0

也许你是对的。不过我想尝试一下。目前我无法设置这个信号。 –

+0

我并不完全满意select的一个原因是select在socket中有实际输入消息之前被调用4次。我猜想select会连续轮询所有I/O描述符,并在所有其他fds准备就绪时回退1。我需要更快的解决方案 –

回答

0

最大的可能是你忘了,包括不管是间接的还是直接的。这是定义标志的地方。

如果未定义O_ASYNC,则可尝试使用该标志的功能等效前驱FASYNC

另外,还要确保你已经在执行

int flags; 

/* Install signal handler here... */ 

/* Set flags to receive SIGIO (and SIGURG) signals */ 
flags = fcntl (F_GETFL, 0); 
flags = fcntl (F_SETFL, flags | FASYNC); 

/* Bind our process as receiver of SIGIO signals */ 
flags = fcntl (F_SETOWN, getpid()); 
+0

我已经包含了fcntl.h,它用于O_NONBLOCK状态标志。我检查fcntl.h,sys/fcntl.h和_default_fcntl.h的所有三个文件。没有提到像O_ASYNC这样的宏。 –

+0

您可以使用'FASINC'吗?这应该是功能上等同的前身。 – tofro

+0

'FASYNC'我打算写 – tofro