Skip to content

Commit bdb1646

Browse files
committed
8364611: (process) Child process SIGPIPE signal disposition should be default
Reviewed-by: erikj, rriggs
1 parent 23985c2 commit bdb1646

File tree

5 files changed

+196
-1
lines changed

5 files changed

+196
-1
lines changed

make/test/JtregNativeJdk.gmk

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ BUILD_JDK_JTREG_LIBRARIES_JDK_LIBS_libGetXSpace := java.base:libjava
6262
ifeq ($(call isTargetOs, windows), true)
6363
BUILD_JDK_JTREG_EXCLUDE += libDirectIO.c libInheritedChannel.c \
6464
libExplicitAttach.c libImplicitAttach.c \
65-
exelauncher.c libFDLeaker.c exeFDLeakTester.c
65+
exelauncher.c libFDLeaker.c exeFDLeakTester.c \
66+
libChangeSignalDisposition.c exePrintSignalDisposition.c
6667

6768
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerTest := $(LIBCXX)
6869
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exerevokeall := advapi32.lib

src/java.base/unix/native/libjava/childproc.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,11 @@ childProcess(void *arg)
426426
sigprocmask(SIG_SETMASK, &unblock_signals, NULL);
427427
}
428428

429+
// Children should be started with default signal disposition for SIGPIPE
430+
if (signal(SIGPIPE, SIG_DFL) == SIG_ERR) {
431+
goto WhyCantJohnnyExec;
432+
}
433+
429434
JDK_execvpe(p->mode, p->argv[0], p->argv, p->envv);
430435

431436
WhyCantJohnnyExec:
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/**
25+
* @test id=posix_spawn
26+
* @bug 8364611
27+
* @summary Check that childs start with SIG_DFL as SIGPIPE disposition
28+
* @requires os.family != "windows"
29+
* @library /test/lib
30+
* @run main/othervm/native -Djdk.lang.Process.launchMechanism=posix_spawn -agentlib:ChangeSignalDisposition TestChildSignalDisposition
31+
*/
32+
33+
/**
34+
* @test id=fork
35+
* @bug 8364611
36+
* @summary Check that childs start with SIG_DFL as SIGPIPE disposition
37+
* @requires os.family != "windows"
38+
* @library /test/lib
39+
* @run main/othervm/native -Djdk.lang.Process.launchMechanism=fork -agentlib:ChangeSignalDisposition TestChildSignalDisposition
40+
*/
41+
42+
/**
43+
* @test id=vfork
44+
* @bug 8364611
45+
* @summary Check that childs start with SIG_DFL as SIGPIPE disposition
46+
* @requires os.family == "linux"
47+
* @library /test/lib
48+
* @run main/othervm/native -Djdk.lang.Process.launchMechanism=vfork -agentlib:ChangeSignalDisposition TestChildSignalDisposition
49+
*/
50+
51+
import jdk.test.lib.process.OutputAnalyzer;
52+
import jdk.test.lib.process.ProcessTools;
53+
public class TestChildSignalDisposition {
54+
// This test has two native parts:
55+
// - a library injected into the JVM with -agentlib changes signal disposition of the VM process for SIGPIPE to
56+
// SIG_IGN
57+
// - a small native executable that prints out, in its main function, all signal handler dispositions, to be executed
58+
// as a child process.
59+
//
60+
// What should happen: In child process, SIGPIPE should be set to default.
61+
public static void main(String[] args) throws Exception {
62+
ProcessBuilder pb = ProcessTools.createNativeTestProcessBuilder("PrintSignalDisposition");
63+
OutputAnalyzer output = ProcessTools.executeProcess(pb);
64+
output.shouldHaveExitValue(0);
65+
output.shouldNotMatch("SIGPIPE: +ignore");
66+
output.shouldNotMatch("SIGPIPE: +block");
67+
output.shouldMatch("SIGPIPE: +default");
68+
output.reportDiagnosticSummary();
69+
}
70+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
#include <errno.h>
25+
#include "jvmti.h"
26+
#include <signal.h>
27+
#include <stdio.h>
28+
#include <unistd.h>
29+
30+
static const struct { int sig; const char* name; } signals[] = {
31+
{ SIGABRT, "SIGABRT" }, { SIGALRM, "SIGALRM" }, { SIGBUS, "SIGBUS" }, { SIGCHLD, "SIGCHLD" }, { SIGCONT, "SIGCONT" },
32+
{ SIGFPE, "SIGFPE" }, { SIGHUP, "SIGHUP" }, { SIGILL, "SIGILL" }, { SIGINT, "SIGINT" }, { SIGKILL, "SIGKILL" },
33+
{ SIGPIPE, "SIGPIPE" }, { SIGQUIT, "SIGQUIT" }, { SIGSEGV, "SIGSEGV" }, { SIGSTOP, "SIGSTOP" }, { SIGTERM, "SIGTERM" },
34+
{ SIGTSTP, "SIGTSTP" }, { SIGTTIN, "SIGTTIN" }, { SIGTTOU, "SIGTTOU" }, { SIGUSR1, "SIGUSR1" }, { SIGUSR2, "SIGUSR2" },
35+
#ifdef SIGPOLL
36+
{ SIGPOLL, "SIGPOLL" },
37+
#endif
38+
{ SIGPROF, "SIGPROF" }, { SIGSYS, "SIGSYS" }, { SIGTRAP, "SIGTRAP" }, { SIGURG, "SIGURG" }, { SIGVTALRM, "SIGVTALRM" },
39+
{ SIGXCPU, "SIGXCPU" }, { SIGXFSZ, "SIGXFSZ" }, { -1, NULL }
40+
};
41+
42+
int main(int argc, char** argv) {
43+
44+
printf("PID: %d\n", getpid());
45+
46+
sigset_t current_mask;
47+
sigemptyset(&current_mask);
48+
if (sigprocmask(SIG_BLOCK /* ignored */, NULL, &current_mask) != 0) {
49+
printf("sigprocmask %d\n", errno);
50+
return -1;
51+
}
52+
53+
for (int n = 0; signals[n].sig != -1; n++) {
54+
printf("%s: ", signals[n].name);
55+
if (sigismember(&current_mask, signals[n].sig)) {
56+
printf("blocked ");
57+
}
58+
struct sigaction act;
59+
if (sigaction(signals[n].sig, NULL, &act) != 0) {
60+
printf("sigaction %d\n", errno);
61+
printf("\n");
62+
continue;
63+
}
64+
const void* const handler = (act.sa_flags & SA_SIGINFO ?
65+
(void*)act.sa_sigaction : (void*)act.sa_handler);
66+
if (handler == (void*)SIG_DFL) {
67+
printf("default ");
68+
} else if (handler == (void*)SIG_IGN) {
69+
printf("ignore ");
70+
} else if (handler == (void*)SIG_HOLD) {
71+
printf("hold ");
72+
} else {
73+
printf("%p ", handler);
74+
}
75+
printf("%X %X\n", act.sa_flags, act.sa_mask);
76+
}
77+
78+
return 0;
79+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
#include <errno.h>
25+
#include "jvmti.h"
26+
#include <signal.h>
27+
#include <stdio.h>
28+
29+
JNIEXPORT jint JNICALL
30+
Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
31+
32+
if (signal(SIGPIPE, SIG_IGN) != SIG_ERR) {
33+
printf("changed signal disposition for SIGPIPE to SIG_IGN\n");
34+
} else {
35+
printf("FAILED to change signal disposition for SIGPIPE to SIG_IGN (%d)\n", errno);
36+
return JNI_ERR;
37+
}
38+
39+
return JNI_OK;
40+
}

0 commit comments

Comments
 (0)