Frage

Unter Linux ist es möglich, irgendwie deaktivieren Signalisierung für Programme extern ... das heißt, ohne den Quellcode zu modifizieren?

Kontext:

Ich rufe eine C ( und auch eine Java ) Programm aus einem Bash-Skript auf Linux. Ich will keine Unterbrechungen für meinen Bash-Skript, und für die anderen Programme, dass die Skript Einführungen (als Vordergrundprozess).

Während ich ...

verwenden kann,
trap '' INT

... in meinem Bash-Skript die Strg-C-Signal zu deaktivieren, funktioniert dies nur, wenn die Programmsteuerung geschieht in der Bash-Code. Das heißt, wenn ich Ctrl C drücken, während das C-Programm ausgeführt wird, wird das C-Programm unterbrochen und es tritt aus! Das C-Programm macht einige kritische Operation, weil von denen ich es nicht will, unterbrochen werden. Ich habe keinen Zugriff auf den Quellcode dieses C-Programms, so Signal innerhalb des C-Programms Umgang mit der Frage aus.

#!/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

Grüße,

/ HS

War es hilfreich?

Lösung

Das Prozesssignal Maske wird über exec geerbt, so dass man einfach ein kleines Wrapper-Programm schreiben kann, dass die Blöcke SIGINT und führt das Ziel:

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

Wenn Sie dieses Programm zu noint kompilieren, würden Sie nur ./noint ./y ausführen.

Wie ephemient Hinweise in den Kommentaren wird das Signal Disposition auch geerbt, so können Sie das haben Wrapper um das Signal zu ignorieren, anstatt sie zu blockieren:

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

(und natürlich auch für einen Riemen und Klammern nähern, könnten Sie beide tun).

Andere Tipps

Die „trap“ -Befehl an diesem Prozess lokal ist, nie für Kinder gilt.

Um wirklich Falle das Signal, haben Sie es hacken einen LD_PRELOAD Haken verwenden. Dies ist nicht-triviale Aufgabe (Sie haben einen ladbaren mit _init(), sigaction() innen zu kompilieren), also werde ich nicht den vollständigen Code hier enthalten. Sie können ein Beispiel für SIGSEGV auf Phack Volume 0x0b, Ausgabe 0x3a, Phile # 0x03 finden .

Alternativlly, versuchen Sie den nohup und tail Trick.

nohup  your_command &
tail -F nohup.out

Ich würde vorschlagen, dass Ihre C (und Java) Bedürfnisse Anwendung Umschreiben, so dass es eine Ausnahme behandeln kann, was passiert, wenn es wirklich notwendig macht unterbrochen, Stromausfall, etc ...

I, die fehlschlägt, J-16 ist direkt auf dem Geld. Hat der Benutzer Notwendigkeit, interract mit dem Prozess, oder einfach nur die Ausgabe sehen (tut sie müssen auch die Ausgabe sehen?)

Die Lösungen oben erläuterten sind nicht für mich arbeiten, auch durch die beiden Befehle Vorschlag Caf verketten.

Allerdings habe ich endlich gelungen, immer das erwartete Verhalten so:

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

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

Wenn ich drücken Sie Strg-C, während child ausgeführt wird, wird es warten, dass sie beendet wird, wird dann drucken AAA und 2. child erhalten keine Signale.

Die Subshell wird verwendet, die PID zu verhindern gezeigt wird.

Und sorry ... das ist für zsh obwohl die Frage für bash ist, aber ich weiß nicht, bash genug, um einen Äquivalent-Skript zur Verfügung zu stellen.

Dies ist Beispielcode von Signalen wie Strg + C für Programme ermöglichen, die sie blockieren.

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

Compile es:

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

Ausführen es:

LD_LIBRARY_PATH=. LD_PRELOAD=fixControlC.so mysqld
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top