从外部禁用Linux程序的信号 [英] Externally disabling signals for a Linux program
问题描述
在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屋!