diff --git a/src/main/java/com/zaxxer/nuprocess/internal/LibC.java b/src/main/java/com/zaxxer/nuprocess/internal/LibC.java index 5a0d24d..532bd9b 100644 --- a/src/main/java/com/zaxxer/nuprocess/internal/LibC.java +++ b/src/main/java/com/zaxxer/nuprocess/internal/LibC.java @@ -81,7 +81,7 @@ public static native int posix_spawnp(IntByReference restrict_pid, String restri // We can't use JNA direct mapping for syscall(), since it takes varargs. public interface SyscallLibrary extends Library { - public static final int SYS___pthread_chdir = 348; + public static final int SYS___pthread_chdir = System.getProperty("os.name").toLowerCase().contains("freebsd") ? 12 : 348; int syscall(int syscall_number, Object... args); } diff --git a/src/main/java/com/zaxxer/nuprocess/osx/LibKevent.java b/src/main/java/com/zaxxer/nuprocess/osx/LibKevent.java index da4990b..f2a6b1f 100644 --- a/src/main/java/com/zaxxer/nuprocess/osx/LibKevent.java +++ b/src/main/java/com/zaxxer/nuprocess/osx/LibKevent.java @@ -59,6 +59,7 @@ public static class Kevent extends Structure public int fflags; public NativeLong data; public Pointer udata; + public long[] ext = new long[4]; public Kevent() { super(); @@ -72,7 +73,12 @@ public Kevent(Pointer p) { @Override protected List getFieldOrder() { - return Arrays.asList("ident", "filter", "flags", "fflags", "data", "udata"); + String osname = System.getProperty("os.name").toLowerCase(); + if(osname.contains("freebsd")){ + return Arrays.asList("ident", "filter", "flags", "fflags", "data", "udata", "ext"); + } else { + return Arrays.asList("ident", "filter", "flags", "fflags", "data", "udata"); + } } Kevent EV_SET(long ident, int filter, int flags, int fflags, long data, Pointer udata) diff --git a/src/main/java/com/zaxxer/nuprocess/osx/ProcessKqueue.java b/src/main/java/com/zaxxer/nuprocess/osx/ProcessKqueue.java index 210bf23..4c1328e 100644 --- a/src/main/java/com/zaxxer/nuprocess/osx/ProcessKqueue.java +++ b/src/main/java/com/zaxxer/nuprocess/osx/ProcessKqueue.java @@ -16,10 +16,13 @@ package com.zaxxer.nuprocess.osx; -import static com.zaxxer.nuprocess.internal.LibC.WEXITSTATUS; -import static com.zaxxer.nuprocess.internal.LibC.WIFEXITED; -import static com.zaxxer.nuprocess.internal.LibC.WIFSIGNALED; -import static com.zaxxer.nuprocess.internal.LibC.WTERMSIG; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.ptr.IntByReference; +import com.zaxxer.nuprocess.internal.BaseEventProcessor; +import com.zaxxer.nuprocess.internal.LibC; +import com.zaxxer.nuprocess.osx.LibKevent.Kevent; +import com.zaxxer.nuprocess.osx.LibKevent.TimeSpec; import java.util.ArrayList; import java.util.Iterator; @@ -28,13 +31,7 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; -import com.sun.jna.Native; -import com.sun.jna.Pointer; -import com.sun.jna.ptr.IntByReference; -import com.zaxxer.nuprocess.internal.BaseEventProcessor; -import com.zaxxer.nuprocess.internal.LibC; -import com.zaxxer.nuprocess.osx.LibKevent.Kevent; -import com.zaxxer.nuprocess.osx.LibKevent.TimeSpec; +import static com.zaxxer.nuprocess.internal.LibC.*; /** * @author Brett Wooldridge @@ -115,14 +112,14 @@ public void registerProcess(OsxProcess process) // We don't use the processEvents array here, since this method is not // called on the event processor thread. Kevent[] events = (Kevent[]) new Kevent().toArray(4); - // Listen for process exit (one-shot event) - events[0].EV_SET((long) pid, Kevent.EVFILT_PROC, Kevent.EV_ADD | Kevent.EV_RECEIPT | Kevent.EV_ONESHOT, - Kevent.NOTE_EXIT | Kevent.NOTE_EXITSTATUS | Kevent.NOTE_REAP, 0L, pidPointer); // Listen for stdout and stderr data availability (events deleted automatically when file descriptors closed) - events[1].EV_SET(stdoutFd, Kevent.EVFILT_READ, Kevent.EV_ADD | Kevent.EV_RECEIPT, 0, 0L, pidPointer); - events[2].EV_SET(stderrFd, Kevent.EVFILT_READ, Kevent.EV_ADD | Kevent.EV_RECEIPT, 0, 0L, pidPointer); + events[0].EV_SET(stdoutFd, Kevent.EVFILT_READ, Kevent.EV_ADD | Kevent.EV_RECEIPT, 0, 0L, pidPointer); + events[1].EV_SET(stderrFd, Kevent.EVFILT_READ, Kevent.EV_ADD | Kevent.EV_RECEIPT, 0, 0L, pidPointer); // Listen for stdin data availability (initially disabled until user wants read, deleted automatically when file descriptor closed) - events[3].EV_SET(stdinFd, Kevent.EVFILT_WRITE, Kevent.EV_ADD | Kevent.EV_DISABLE | Kevent.EV_RECEIPT, 0, 0L, pidPointer); + events[2].EV_SET(stdinFd, Kevent.EVFILT_WRITE, Kevent.EV_ADD | Kevent.EV_DISABLE | Kevent.EV_RECEIPT, 0, 0L, pidPointer); + // Listen for process exit (one-shot event) + events[3].EV_SET((long) pid, Kevent.EVFILT_PROC, Kevent.EV_ADD | Kevent.EV_RECEIPT | Kevent.EV_ONESHOT, + Kevent.NOTE_EXIT | Kevent.NOTE_EXITSTATUS | Kevent.NOTE_REAP, 0L, pidPointer); registerEvents(events, 4); } finally {