You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中按下Ctrl+C时删除FIFO文件的信号处理函数问题

问题分析与解决方案

嘿,我一眼就揪出你代码里的核心问题啦:信号处理函数的签名不符合标准,这会导致程序运行时出现未定义行为,根本没法正常执行你想要的FIFO删除操作。

核心问题

POSIX标准明确规定,信号处理函数的原型只能是:

void handler(int sig);

而你写的sigintHandler多了一个char * myfifo参数,这完全不符合要求——当内核触发信号处理函数时,只会传递信号编号这一个参数,多余的参数会直接造成栈混乱,函数里的unlink自然也没法正确执行。

两种修复方案

方案1:用全局变量存储FIFO路径(简单直接)

把FIFO路径定义为全局变量,这样信号处理函数就能直接访问到它,是最容易上手的解决方式:

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>

#define MAX_BUF 512
char *g_myfifo; // 全局变量存储FIFO路径

void sigintHandler(int sig_num) {
    puts("Hello you there, please don't leave!");
    if (g_myfifo != NULL) {
        // 可选:检查删除操作是否成功
        if (unlink(g_myfifo) == -1) {
            perror("Failed to delete FIFO");
        } else {
            printf("Deleted FIFO file: %s\n", g_myfifo);
        }
    }
    exit(0);
}

int main() {
    g_myfifo = "/tmp/my_fifo"; // 先初始化全局变量
    mkfifo(g_myfifo, 0666);

    // 注册SIGINT信号处理函数
    signal(SIGINT, sigintHandler);

    // 这里写你的主逻辑(比如读写FIFO的代码)
    // ...

    return 0;
}

方案2:用sigaction传递上下文(优雅避全局)

如果你不想用全局变量,可以借助sigaction的扩展机制传递自定义上下文,不过这种方式更适合自定义信号场景,对于Ctrl+C触发的SIGINT,需要额外处理上下文的存储:

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

#define MAX_BUF 512
static char s_fifo_path[256]; // 用静态全局变量存储路径,避免污染全局命名空间

void sigintHandler(int sig_num, siginfo_t *info, void *ucontext) {
    puts("Hello you there, please don't leave!");
    if (strlen(s_fifo_path) > 0) {
        if (unlink(s_fifo_path) == -1) {
            perror("Failed to delete FIFO");
        } else {
            printf("Deleted FIFO file: %s\n", s_fifo_path);
        }
    }
    exit(0);
}

int main() {
    strcpy(s_fifo_path, "/tmp/my_fifo");
    mkfifo(s_fifo_path, 0666);

    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_sigaction = sigintHandler;
    sa.sa_flags = SA_SIGINFO; // 启用带扩展参数的信号处理函数

    // 注册信号处理规则
    sigaction(SIGINT, &sa, NULL);

    // 主逻辑代码
    // ...

    return 0;
}

额外小提示

  • 一定要先初始化FIFO路径,再注册信号处理函数,避免删除空路径导致错误。
  • 加上perror判断删除结果,能帮你快速排查权限不足、文件不存在之类的问题。

内容的提问来源于stack exchange,提问作者Oussema Ben Abdallah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:26:28