hac*_*cks 2 c linux operating-system
我有一个最小的工作代码,它应该读取用户输入并处理任何 SIGINT (ctrl+c)。我用了sigaction。如果按下 ctrl+c,它将$在新行上打印 a 并等待用户输入。
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
volatile sig_atomic_t sigint_received = 0;
static void handler(int signum)
{
sigint_received = 1;
}
int main()
{
struct sigaction sa;
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
char *line = NULL;
size_t n = 100;
line = malloc(n);
while(1){
if(sigint_received){
sigint_received = 0;
printf("\n");
}
printf("$ ");
getline(&line, &n, stdin);
if(!strcmp(line, "exit\n")){
break;
}
}
if(line){
free(line);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我做了预期的事情(无意中)。我的问题是操作系统处理中断后为什么getline不等待输入?程序不应该从中断处继续吗?
免责声明:我不擅长 Linux 编程,如果这是一个菜鸟问题,很抱歉。
感谢@user3386109和@Emanuel P的富有洞察力的评论。sigaction我检查了 Mac上的手册页getline,发现如下:
man sigaction:
SA_RESTART 请参阅下面的段落。
进而
如果在下面列出的系统调用期间捕获到信号,则调用可能会因错误而被迫终止
EINTR,调用可能会返回比请求的数据传输短的数据传输,或者调用可能会重新启动。SA_RESTART通过设置中的位来请求重新启动挂起的呼叫sa_flags。受影响的系统调用包括通信通道或慢速设备(例如终端,但不是常规文件)上的open(2)、read(2)、write(2)、sendto(2)、recvfrom(2)和,以及在或期间。...sendmsg(2)recvmsg(2)wait(2)ioctl(2)
并在失败时getline返回-1。它在这里说:
如果发生故障,
errno则设置为指示错误。
在这种情况下errno将被设置为评论EINTR中指出的。
处理完中断后程序将恢复运行getline并且不会等待用户输入。相反,如上所述,它将因错误而终止EINTR。
固定代码:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
volatile sig_atomic_t sigint_received = 0;
static void handler(int signum)
{}
int main()
{
struct sigaction sa;
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
char *line = NULL;
size_t n = 100;
line = malloc(n);
while(1){
printf("$ ");
ssize_t ret = getline(&line, &n, stdin);
if(ret == -1 && errno == EINTR){
printf("\n");
errno = 0; // Reset errno flag
continue;
}
if(!strcmp(line, "exit\n")){
break;
}
}
if(line){
free(line);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
266 次 |
| 最近记录: |