I've got a program with a specialized Process
-type class which handles executing the processes natively on Linux.
It does not use Java's Process class at all, because it needs to do some special handling of the process. Because of this, it also installs its own signal handler for SIGCHLD
, so that it knows when a process exits.
However, I just added a Runtime.exec()
call in my code, which apparently installs its own signal handler for SIGCHLD
, which means that I never get a SIGCHLD
again, which is bad. I've followed the signal-chaining instructions from oracle, but the same problem happens, I never get a SIGCHLD
.
So, the basic question is this: is it possible to chain SIGCHLD
in Java?
libjsig
does not help, because SIGCHLD
handler is installed by libjava
, not by JVM itself.
sigaction(SIGCHLD, ...)
with sa_handler = SIG_DFL
is called only once by Java Class Library in the static initializer of java.lang.UNIXProcess.
Now you have the following options to work-around this.
The easiest one. Just install your signal handler after initialization of java.lang.UNIXProcess
.
Create your own LD_PRELOAD
hook that will intercept sigaction
and ignore it when called with SIGCHLD
and SIG_DFL
arguments:
E.g.
#define _GNU_SOURCE
#include <signal.h>
#include <dlfcn.h>
#include <stddef.h>
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);
}