When a command invoked from readPipe fails to launch (i.e. the exec call fails due to a missing command executable), Process.start() throws, which gets caught by the generic IOException handler, resulting in a null return. This change detects this case and rethrows a CommandFailedException instead. Additionally, this change uses /bin/sh instead of bash for its posix command failure test, to accomodate building in environments where bash is unavailable. Change-Id: Ifae51e457e5718be610c0a0914b18fe35ea7b008 Signed-off-by: Bryan Donlan <bdonlan@gmail.com> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>tags/v4.8.0.201706111038-r
@@ -172,9 +172,18 @@ public class FSTest { | |||
FS fs = FS.DETECTED.newInstance(); | |||
assumeTrue(fs instanceof FS_POSIX); | |||
String r = FS.readPipe(fs.userHome(), | |||
new String[] { "bash", "--login", "-c", "foobar" }, | |||
FS.readPipe(fs.userHome(), | |||
new String[] { "/bin/sh", "-c", "exit 1" }, | |||
Charset.defaultCharset().name()); | |||
System.out.println(r); | |||
} | |||
@Test(expected = CommandFailedException.class) | |||
public void testReadPipeCommandStartFailure() | |||
throws CommandFailedException { | |||
FS fs = FS.DETECTED.newInstance(); | |||
FS.readPipe(fs.userHome(), | |||
new String[] { "this-command-does-not-exist" }, | |||
Charset.defaultCharset().name()); | |||
} | |||
} |
@@ -497,7 +497,13 @@ public abstract class FS { | |||
if (env != null) { | |||
pb.environment().putAll(env); | |||
} | |||
Process p = pb.start(); | |||
Process p; | |||
try { | |||
p = pb.start(); | |||
} catch (IOException e) { | |||
// Process failed to start | |||
throw new CommandFailedException(-1, e.getMessage(), e); | |||
} | |||
p.getOutputStream().close(); | |||
GobblerThread gobbler = new GobblerThread(p, command, dir); | |||
gobbler.start(); |