我可以关闭信号处理程序中的文件描述符吗?

Can I close a file descriptor inside a signal handler?

目前在我的 类 中,我们正在学习如何在 C 中处理信号。我发现它非常有趣,所以我一直在弄乱它以尝试很好地学习它。
这就是问题所在:我想制作一个程序,在无限循环中从 stdin 读取并将输入的内容写入文件。当我想让它停止时,我只需使用 CTRL + C 并终止程序。
我想弄乱信号函数以使它更优雅地终止,但是它不起作用。谁能告诉我如何获得所需的行为?
这是我的代码:

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

void sigint_handler (int signum) {
    printf("\nTerminating program...\n");
    close(fd);
    _exit(0);
}

int main (int argc, char *argv[]) {
    signal(SIGINT, sigint_handler);
    int fd;
    if ((fd = open("client", O_WRONLY | O_CREAT)) == -1) {
        perror("Error opening file");
        return 1;
    }
    int len = 0;
    char buffer[1024];
    while ((len = read(STDIN_FILENO, buffer, 1024)) > 0) {
        write(fd, buffer, len);
    }
    printf("Terminated\n");
    close(fd);
    return 0;
}

重点是在 sigint_handler() 函数内部,它将关闭文件描述符并终止程序。
但是,我不能这样做。有没有更好的方法来得到想要的结果?
还是可以在不关闭文件描述符的情况下终止程序? 如果有人能帮助我更好地理解这一点,我将不胜感激。

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

#define TERMINATING "\nTerminating program...\n"

void sigint_handler (int signum) {
    // you can use write to avoid issues raised by @Shawn
    write(2, TERMIATING, sizeof(TERMINATING));
    _exit(0); /* close is not needed _exit guarantees the close */
}

int main (int argc, char *argv[]) 
{
    int fd;
    if ((fd = open("client", O_WRONLY | O_CREAT)) == -1) {
        perror("Error opening file");
        return 1;
    }

    // install signal handler ONLY AFTER successfully opening fd
    signal(SIGINT, sigint_handler);

    int len = 0;
    char buffer[1024];
    while ((len = read(STDIN_FILENO, buffer, 1024)) > 0) {
        write(fd, buffer, len);
    }
    // print messages like this to stderr 
    fprintf(stderr, "Terminated\n");
    close(fd); // superfluous because you are about exit
    return 0;
}

执行处理程序的更好方法是将 fd 保留在 main 本地,但是使用 exit(0) 而不是 _exit 因为 exit(0) 会导致内核关闭所有正在运行的文件打开。