8216134: (process) ProcessBuilder startPipeline does not hide piped streams

Reviewed-by: lancea, bchristi, sgroeger
This commit is contained in:
Roger Riggs 2019-01-07 09:29:31 -05:00
parent 91a88da167
commit eefbe6709f
2 changed files with 26 additions and 13 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -106,6 +106,7 @@ final class ProcessImpl extends Process {
FileOutputStream f2 = null; FileOutputStream f2 = null;
try { try {
boolean forceNullOutputStream = false;
long[] stdHandles; long[] stdHandles;
if (redirects == null) { if (redirects == null) {
stdHandles = new long[] { -1L, -1L, -1L }; stdHandles = new long[] { -1L, -1L, -1L };
@ -129,6 +130,9 @@ final class ProcessImpl extends Process {
stdHandles[1] = fdAccess.getHandle(FileDescriptor.out); stdHandles[1] = fdAccess.getHandle(FileDescriptor.out);
} else if (redirects[1] instanceof ProcessBuilder.RedirectPipeImpl) { } else if (redirects[1] instanceof ProcessBuilder.RedirectPipeImpl) {
stdHandles[1] = fdAccess.getHandle(((ProcessBuilder.RedirectPipeImpl) redirects[1]).getFd()); stdHandles[1] = fdAccess.getHandle(((ProcessBuilder.RedirectPipeImpl) redirects[1]).getFd());
// Force getInputStream to return a null stream,
// the handle is directly assigned to the next process.
forceNullOutputStream = true;
} else { } else {
f1 = newFileOutputStream(redirects[1].file(), f1 = newFileOutputStream(redirects[1].file(),
redirects[1].append()); redirects[1].append());
@ -149,7 +153,7 @@ final class ProcessImpl extends Process {
} }
Process p = new ProcessImpl(cmdarray, envblock, dir, Process p = new ProcessImpl(cmdarray, envblock, dir,
stdHandles, redirectErrorStream); stdHandles, forceNullOutputStream, redirectErrorStream);
if (redirects != null) { if (redirects != null) {
// Copy the handles's if they are to be redirected to another process // Copy the handles's if they are to be redirected to another process
if (stdHandles[0] >= 0 if (stdHandles[0] >= 0
@ -349,6 +353,7 @@ final class ProcessImpl extends Process {
final String envblock, final String envblock,
final String path, final String path,
final long[] stdHandles, final long[] stdHandles,
boolean forceNullOutputStream,
final boolean redirectErrorStream) final boolean redirectErrorStream)
throws IOException throws IOException
{ {
@ -437,7 +442,7 @@ final class ProcessImpl extends Process {
new FileOutputStream(stdin_fd)); new FileOutputStream(stdin_fd));
} }
if (stdHandles[1] == -1L) if (stdHandles[1] == -1L || forceNullOutputStream)
stdout_stream = ProcessBuilder.NullInputStream.INSTANCE; stdout_stream = ProcessBuilder.NullInputStream.INSTANCE;
else { else {
FileDescriptor stdout_fd = new FileDescriptor(); FileDescriptor stdout_fd = new FileDescriptor();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -34,6 +34,8 @@ import java.util.List;
/* /*
* @test PipelineTest * @test PipelineTest
* @bug 8211844
* @summary Tests for ProcessBuilder.startPipeline
*/ */
public class PipelineTest { public class PipelineTest {
@ -170,7 +172,7 @@ public class PipelineTest {
static void verify(String input, String expected, List<ProcessBuilder> builders) throws IOException { static void verify(String input, String expected, List<ProcessBuilder> builders) throws IOException {
File infile = new File("test.in"); File infile = new File("test.in");
File outfile = new File("test.out"); File outfile = new File("test.out");
setFileContents(infile, expected); setFileContents(infile, input);
for (int i = 0; i < builders.size(); i++) { for (int i = 0; i < builders.size(); i++) {
ProcessBuilder b = builders.get(i); ProcessBuilder b = builders.get(i);
if (i == 0) { if (i == 0) {
@ -184,8 +186,8 @@ public class PipelineTest {
verifyProcesses(processes); verifyProcesses(processes);
waitForAll(processes); waitForAll(processes);
String result = fileContents(outfile); String result = fileContents(outfile);
System.out.printf(" in: %s%nout: %s%n", input, expected); check(result.equals(expected),
check(result.equals(expected), "result not as expected"); "result not as expected: " + result + ", expected: " + expected);
} }
/** /**
@ -219,11 +221,14 @@ public class PipelineTest {
static void verifyProcesses(List<Process> processes) { static void verifyProcesses(List<Process> processes) {
for (int i = 0; i < processes.size(); i++) { for (int i = 0; i < processes.size(); i++) {
Process p = processes.get(i); Process p = processes.get(i);
if (i != 0) { if (i != 0) {
verifyNullStream(p.getOutputStream(), "getOutputStream"); verifyNullStream(p.getOutputStream(), "getOutputStream");
} }
if (i == processes.size() - 1) { if (i <= processes.size() - 1) {
verifyNullStream(p.getInputStream(), "getInputStream"); verifyNullStream(p.getInputStream(), "getInputStream");
}
if (i == processes.size() - 1) {
verifyNullStream(p.getErrorStream(), "getErrorStream"); verifyNullStream(p.getErrorStream(), "getErrorStream");
} }
} }
@ -232,7 +237,7 @@ public class PipelineTest {
static void verifyNullStream(OutputStream s, String msg) { static void verifyNullStream(OutputStream s, String msg) {
try { try {
s.write(0xff); s.write(0xff);
fail("Stream should have been a NullStream" + msg); fail("Stream should have been a NullStream: " + msg);
} catch (IOException ie) { } catch (IOException ie) {
// expected // expected
} }
@ -241,7 +246,7 @@ public class PipelineTest {
static void verifyNullStream(InputStream s, String msg) { static void verifyNullStream(InputStream s, String msg) {
try { try {
int len = s.read(); int len = s.read();
check(len == -1, "Stream should have been a NullStream" + msg); check(len == -1, "Stream should have been a NullStream: " + msg);
} catch (IOException ie) { } catch (IOException ie) {
// expected // expected
} }
@ -271,9 +276,12 @@ public class PipelineTest {
//--------------------- Infrastructure --------------------------- //--------------------- Infrastructure ---------------------------
static volatile int passed = 0, failed = 0; static volatile int passed = 0, failed = 0;
static void pass() {passed++;} static void pass() {passed++;}
static void fail() {failed++; Thread.dumpStack();} static void fail() {failed++; new Exception("Stack trace").printStackTrace(System.out);}
static void fail(String msg) {System.err.println(msg); fail();} static void fail(String msg) {
static void unexpected(Throwable t) {failed++; t.printStackTrace();} System.out.println(msg); failed++;
new Exception("Stack trace: " + msg).printStackTrace(System.out);
}
static void unexpected(Throwable t) {failed++; t.printStackTrace(System.out);}
static void check(boolean cond) {if (cond) pass(); else fail();} static void check(boolean cond) {if (cond) pass(); else fail();}
static void check(boolean cond, String m) {if (cond) pass(); else fail(m);} static void check(boolean cond, String m) {if (cond) pass(); else fail(m);}
static void equal(Object x, Object y) { static void equal(Object x, Object y) {