Вопрос

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.

  1. The easiest one. Just install your signal handler after initialization of java.lang.UNIXProcess.

  2. 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);
}

Другие советы

How about using sockets to communicate with your child process in stead of SIGCHLD? I assume you create the child process code yourself.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top