带有 siglongjmp 中断 I/O 的异常处理程序

问题描述 投票:0回答:1

在处理 CSAPP 中的作业问题 8.25 时,我参考了其解决方案:https://dreamanddead.github.io/CSAPP-3e-Solutions/。提供的解决方案包括以下 C 代码:

#include <stdio.h>
#include "csapp.h"

sigjmp_buf buf;

void handler(int sig) {
  /* jump */
  siglongjmp(buf, 1);
}

char* tfgets(char* s, int size, FILE* stream) {
  char* result;

  if (!sigsetjmp(buf, 1)) {
    alarm(5);
    if (signal(SIGALRM, handler) == SIG_ERR)
      unix_error("set alarm handler error");
    return fgets(s, size, stream);
  } else {
    /* run out of time */
    return NULL;
  }
}

tfgets
功能是
fgets
具有超时功能。然而,使用 siglongjmp 跳出 IO 操作的安全性令人担忧。

使用 siglongjmp 中断 IO 操作并突然退出是否安全?

我在 stackoverflow 上找不到任何文档或相关问题。

c exception io exceptionhandler setjmp
1个回答
0
投票

不! 从这个处理程序中执行 siglongjmp

安全的。您可以破坏
fgets
正在运行的流的状态。

不要执行

sigsetjmp/siglongjmp
,而是让信号处理程序设置一个全局变量(例如
volatile int alarm_fired;)

然后,如果处理程序触发,

fgets
应返回
NULL
并且
errno
应设置为
EINTR

您可以(安全地)检查返回值和

errno
值。您还可以检查
alarm_fired


旁注: 你有竞争条件。

在执行

signal
之后设置信号处理程序(使用
alarm
)。在系统负载较重的情况下,信号可能会在您有机会设置处理程序之前触发。

alarm
放在
signal
调用之后。

© www.soinside.com 2019 - 2024. All rights reserved.