从外部禁用Linux程序的信号 [英] Externally disabling signals for a Linux program

查看:105
本文介绍了从外部禁用Linux程序的信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Linux上,是否可以通过某种方式禁用外部 ...程序的信号发送,即无需修改其源代码?

On Linux, is it possible to somehow disable signaling for programs externally... that is, without modifying their source code?

上下文:

我正在从Linux上的bash脚本中调用C(以及Java )程序.我不希望我的bash脚本以及该脚本启动的其他程序(作为前台进程)受到任何干扰.

I'm calling a C (and also a Java) program from within a bash script on Linux. I don't want any interruptions for my bash script, and for the other programs that the script launches (as foreground processes).

虽然我可以使用...

While I can use a...

trap '' INT

在我的bash脚本中

...禁用Ctrl C信号,这仅在程序控件恰好在bash代码中时才有效.也就是说,如果我在C程序运行时按Ctrl C,则C程序将被中断并退出!这个C程序正在执行一些关键操作,因此我不希望它被打断.我无权访问此C程序的源代码,因此C程序内部的信号处理毫无疑问.

... in my bash script to disable the Ctrl C signal, this works only when the program control happens to be in the bash code. That is, if I press Ctrl C while the C program is running, the C program gets interrupted and it exits! This C program is doing some critical operation because of which I don't want it be interrupted. I don't have access to the source code of this C program, so signal handling inside the C program is out of question.

#!/bin/bash

trap 'echo You pressed Ctrl C' INT 

# A C program to emulate a real-world, long-running program,
# which I don't want to be interrupted, and for which I 
# don't have the source code!
#
# File: y.c
# To build: gcc -o y y.c
#
# #include <stdio.h>
# int main(int argc, char *argv[]) {
#  printf("Performing a critical operation...\n");
#    for(;;); // Do nothing forever.
#  printf("Performing a critical operation... done.\n");
# }

./y

此致

/HS

推荐答案

过程信号掩码跨exec继承,因此您只需编写一个阻止SIGINT并执行目标的小型包装程序即可.

The process signal mask is inherited across exec, so you can simply write a small wrapper program that blocks SIGINT and executes the target:

#include <signal.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
        sigset_t sigs;

        sigemptyset(&sigs);
        sigaddset(&sigs, SIGINT);
        sigprocmask(SIG_BLOCK, &sigs, 0);

        if (argc > 1) {
                execvp(argv[1], argv + 1);
                perror("execv");
        } else {
                fprintf(stderr, "Usage: %s <command> [args...]\n", argv[0]);
        }
        return 1;
}

如果将此程序编译为noint,则只需执行./noint ./y.

If you compile this program to noint, you would just execute ./noint ./y.

正如在注释中的短暂注解一样,信号的处理方式也是继承的,因此您可以让包装器忽略信号而不是将其阻止:

As ephemient notes in comments, the signal disposition is also inherited, so you can have the wrapper ignore the signal instead of blocking it:

#include <signal.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
        struct sigaction sa = { 0 };

        sa.sa_handler = SIG_IGN;
        sigaction(SIGINT, &sa, 0);

        if (argc > 1) {
                execvp(argv[1], argv + 1);
                perror("execv");
        } else {
                fprintf(stderr, "Usage: %s <command> [args...]\n", argv[0]);
        }
        return 1;
}

(当然,对于皮带和牙套方法,您可以同时使用两者).

(and of course for a belt-and-braces approach, you could do both).

这篇关于从外部禁用Linux程序的信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆