package com.nominanuda.zen.ffi; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.util.Arrays; import java.util.List; import org.junit.BeforeClass; import org.junit.Test; import jnr.ffi.Library; import jnr.ffi.Platform; import jnr.ffi.annotations.Out; import jnr.posix.POSIX; import jnr.posix.POSIXFactory; import jnr.posix.SpawnFileAction; import jnr.posix.util.DefaultPOSIXHandler; import static org.junit.Assert.*; import static jnr.posix.SpawnFileAction.*; public class TestProcessBuilder { private static POSIX posix; private static LibC libc; private static final List<String> emptyEnv = Arrays.asList(new String[0]); private static final List<SpawnFileAction> emptyActions = Arrays.asList(new SpawnFileAction[0]); public static interface LibC { int pipe(@Out int[] fds); } @BeforeClass public static void setUpClass() throws Exception { if (Platform.getNativePlatform().isUnix()) { posix = POSIXFactory.getPOSIX(new DefaultPOSIXHandler(), true); libc = Library.loadLibrary(LibC.class, "c"); } } @Test public void inputPipe() { if (Platform.getNativePlatform().isUnix()) { int[] outputPipe = { -1, -1 }; int[] inputPipe = { -1, -1 }; long pid = -1; try { assertFalse(libc.pipe(outputPipe) < 0); assertFalse(libc.pipe(inputPipe) < 0); assertNotSame(-1, outputPipe[0]); assertNotSame(-1, outputPipe[1]); assertNotSame(-1, inputPipe[0]); assertNotSame(-1, inputPipe[1]); List<SpawnFileAction> actions = Arrays.asList(dup(inputPipe[0], 0), dup(outputPipe[1], 1)); pid = posix.posix_spawnp("cat", actions, Arrays.asList("cat", "-"), emptyEnv); assertTrue(pid != -1); posix.libc().close(inputPipe[0]); assertEquals(3, posix.libc().write(inputPipe[1], ByteBuffer.wrap("foo".getBytes(Charset.forName("US-ASCII"))), 3)); posix.libc().close(inputPipe[1]); // send EOF to process // close the write side of the output pipe, so read() will return immediately once the process has exited posix.libc().close(outputPipe[1]); ByteBuffer output = ByteBuffer.allocate(100); long nbytes = posix.libc().read(outputPipe[0], output, output.remaining()); assertEquals(3L, nbytes); output.position((int) nbytes).flip(); byte[] bytes = new byte[output.remaining()]; output.get(bytes); assertEquals("foo", new String(bytes).trim()); } finally { closePipe(outputPipe); closePipe(inputPipe); killChild(pid); } } } private static void closePipe(int[] fds) { posix.libc().close(fds[0]); posix.libc().close(fds[1]); } private static void killChild(long pid) { if (pid > 0) { posix.libc().kill((int) pid, 9); posix.libc().waitpid((int) pid, null, 0); } } }