質問

Linuxでは、プログラムのシグナリングを何らかの形で無効にすることは可能ですか 外部...つまり、ソースコードを変更せずに?

コンテクスト:

私はcを呼んでいます(また、ジャバ)LinuxのBashスクリプト内からプログラム。 Bashスクリプトや、スクリプトが起動する他のプログラム(前景プロセスとして)の中断は必要ありません。

使用できますが...

trap '' INT

... Ctrl C信号を無効にする私のBASHスクリプトでは、これはプログラム制御がたまたまBASHコードにある場合にのみ機能します。つまり、Cプログラムの実行中にCtrl Cを押すと、Cプログラムが中断され、終了します!このCプログラムは、私がそれを中断したくないので、いくつかの重要な操作を行っています。このCプログラムのソースコードにアクセスできないため、Cプログラム内での信号処理は問題外です。

#!/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 ターゲットを実行します。

#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.

コメントでは効果的なものとして、信号の処分も継承されているため、ラッパーにブロックする代わりに信号を無視させることができます。

#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;
}

(そしてもちろん、ベルトとブレースのアプローチの場合、両方を行うことができます)。

他のヒント

「トラップ」コマンドはこのプロセスのローカルであり、子供には決して適用されません。

本当に信号をトラップするには、 LD_PRELOAD 針。これは非勝利のタスクです(ロード可能なものをコンパイルする必要があります _init(), sigaction() 内部)、だから私はここに完全なコードを含めません。 sigsegvの例を見つけることができます Phack Volume 0x0b、Issue 0x3a、Phile#0x03.

代わりに、試してみてください nohuptail 騙す。

nohup  your_command &
tail -F nohup.out

私はあなたのC(およびJava)アプリケーションが例外を処理できるように書き換えを必要とすることをお勧めします。

私は失敗します、J-16はお金にぴったりです。ユーザーはプロセスと互換性を補う必要がありますか、それとも出力を確認する必要がありますか(出力を確認する必要さえありますか?)

上記のソリューションは、CAFによって提案された両方のコマンドをチェックすることによって、私にとっては機能していません。

しかし、私はついにこのように期待される行動を取得することに成功しました:

#!/bin/zsh
setopt MONITOR
TRAPINT() { print AAA }

print 1
( ./child & ; wait)
print 2

ctrl-cを押すと child 実行されています、それが出るのを待ってから、AAAと2を印刷します。 child 信号は受けられません。

サブシェルは、PIDが表示されないようにするために使用されます。

申し訳ありません...これはZSHのためですが、問題はBashのためですが、同等のスクリプトを提供するのに十分なBashを知りません。

これは、それをブロックするプログラムのCtrl+Cのような信号を有効にするコードの例です。

FixControlc.C

#include <stdio.h>
#include <signal.h>
int sigaddset(sigset_t *set, int signo) {
    printf("int sigaddset(sigset_t *set=%p, int signo=%d)\n", set, signo);
    return 0;
}

コンパイル:

gcc -fPIC -shared -o fixControlC.so fixControlC.c

それを実行します:

LD_LIBRARY_PATH=. LD_PRELOAD=fixControlC.so mysqld
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top