J’ai un programme avec une classe de type de Process
spécialisée qui gère l’exécution des processus en mode natif sous Linux.
Il n’utilise pas du tout la classe de processus de Java, car il doit faire un traitement spécial du processus. De ce fait, il installe également son propre gestionnaire de signaux pour SIGCHLD
, de sorte qu’il sache quand un processus se termine.
Cependant, je viens d’append un appel à Runtime.exec()
dans mon code, qui installe apparemment son propre gestionnaire de signal pour SIGCHLD
, ce qui signifie que je ne reçois plus jamais de SIGCHLD
, ce qui est mauvais. J’ai suivi les instructions de chaînage d’ oracle , mais le même problème se produit, je n’ai jamais de SIGCHLD
.
Donc, la question de base est la suivante: est-il possible de chaîner SIGCHLD
en Java?
libjsig
n’aide pas, car le gestionnaire SIGCHLD
est installé par libjava
et non par la JVM elle-même.
sigaction(SIGCHLD, ...)
avec sa_handler = SIG_DFL
est appelée une seule fois par Java Class Library dans l’initialiseur statique de java.lang.UNIXProcess.
Vous disposez maintenant des options suivantes pour contourner ce problème.
Le plus facile Installez simplement votre gestionnaire de signal après l’ initialisation de java.lang.UNIXProcess
.
Créez votre propre hook LD_PRELOAD
qui interceptera sigaction
et l’ignorera lorsqu’il sera appelé avec les arguments SIGCHLD
et SIG_DFL
:
Par exemple
#define _GNU_SOURCE #include #include #include int sigaction(int signum, const struct sigaction* act, struct sigaction* oldact) { static int (*real_sa)(int, const struct sigaction*, struct sigaction*) = NULL; if (signum == SIGCHLD && act->sa_handler == SIG_DFL) { return 0; } if (real_sa == NULL) { real_sa = dlsym(RTLD_NEXT, "sigaction"); } return real_sa(signum, act, oldact); }
Que diriez-vous d’utiliser des sockets pour communiquer avec votre processus enfant au lieu de SIGCHLD? Je suppose que vous créez le code de processus enfant vous-même.