Chaînage du signal Java

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.

  1. Le plus facile Installez simplement votre gestionnaire de signal après l’ initialisation de java.lang.UNIXProcess .

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