diff --git a/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/SunMiscSubstitutions.java b/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/SunMiscSubstitutions.java index 112a7290e3a5..140b3f34fdbd 100644 --- a/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/SunMiscSubstitutions.java +++ b/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/SunMiscSubstitutions.java @@ -401,15 +401,15 @@ protected long decrementCount() { } @AutomaticallyRegisteredFeature -class IgnoreSIGPIPEFeature implements InternalFeature { +class IgnoreSignalsFeature implements InternalFeature { @Override public void beforeAnalysis(BeforeAnalysisAccess access) { - RuntimeSupport.getRuntimeSupport().addStartupHook(new IgnoreSIGPIPEStartupHook()); + RuntimeSupport.getRuntimeSupport().addStartupHook(new IgnoreSignalsStartupHook()); } } -final class IgnoreSIGPIPEStartupHook implements RuntimeSupport.Hook { +final class IgnoreSignalsStartupHook implements RuntimeSupport.Hook { @CEntryPoint(publishAs = Publish.NotPublished) @CEntryPointOptions(prologue = NoPrologue.class, epilogue = NoEpilogue.class) @@ -418,20 +418,24 @@ static void noopSignalHandler(@SuppressWarnings("unused") int sig) { } private static final CEntryPointLiteral NOOP_SIGNAL_HANDLER = // - CEntryPointLiteral.create(IgnoreSIGPIPEStartupHook.class, "noopSignalHandler", int.class); + CEntryPointLiteral.create(IgnoreSignalsStartupHook.class, "noopSignalHandler", int.class); /** + * HotSpot ignores the SIGPIPE and SIGXFSZ signals (see signals_posix.cpp). + * When signal handling is enabled we do the same thing. + *

* Ignore SIGPIPE. Reading from a closed pipe, instead of delivering a process-wide signal whose * default action is to terminate the process, will instead return an error code from the * specific write operation. - * + *

* From pipe(7): If all file descriptors referring to the read end of a pipe have been closed, * then a write(2) will cause a SIGPIPE signal to be generated for the calling process. If the * calling process is ignoring this signal, then write(2) fails with the error EPIPE. - * + *

* Note that the handler must be an empty function and not SIG_IGN. The problem is SIG_IGN is * inherited to subprocess but we only want to affect the current process. - * + *

* From signal(7): A child created via fork(2) inherits a copy of its parent's signal * dispositions. During an execve(2), the dispositions of handled signals are reset to the * default; the dispositions of ignored signals are left unchanged. @@ -440,15 +444,21 @@ static void noopSignalHandler(@SuppressWarnings("unused") int sig) { public void execute(boolean isFirstIsolate) { if (isFirstIsolate && SubstrateOptions.EnableSignalHandling.getValue()) { synchronized (Target_jdk_internal_misc_Signal.class) { - int signum = Signal.SignalEnum.SIGPIPE.getCValue(); - if (Util_jdk_internal_misc_Signal.isCurrentDispatcher(signum, Signal.SIG_DFL())) { - /* - * Replace with NOOP signal handler if a custom one has not already been - * installed. - */ - final SignalDispatcher signalResult = PosixUtils.installSignalHandler(signum, NOOP_SIGNAL_HANDLER.getFunctionPointer()); - VMError.guarantee(signalResult != Signal.SIG_ERR(), "IgnoreSIGPIPEFeature.run: Could not ignore SIGPIPE"); - } + installNoopHandler(Signal.SignalEnum.SIGPIPE); + installNoopHandler(Signal.SignalEnum.SIGXFSZ); + } + } + } + + private static void installNoopHandler(Signal.SignalEnum signal) { + int signum = signal.getCValue(); + if (Util_jdk_internal_misc_Signal.isCurrentDispatcher(signum, Signal.SIG_DFL())) { + /* + * Replace with no-op signal handler if a custom one has not already been installed. + */ + final SignalDispatcher signalResult = PosixUtils.installSignalHandler(signum, NOOP_SIGNAL_HANDLER.getFunctionPointer()); + if (signalResult == Signal.SIG_ERR()) { + throw VMError.shouldNotReachHere(String.format("IgnoreSignalsStartupHook: Could not install signal: %s", signal)); } } }