$OpenBSD: patch-jdk_src_solaris_native_java_lang_UNIXProcess_md_c,v 1.5 2009/10/07 01:53:54 kurt Exp $
--- jdk/src/solaris/native/java/lang/UNIXProcess_md.c.orig	Thu Sep 17 03:52:32 2009
+++ jdk/src/solaris/native/java/lang/UNIXProcess_md.c	Sun Oct  4 22:01:04 2009
@@ -40,7 +40,11 @@
 #include <stdlib.h>
 #include <sys/types.h>
 #include <ctype.h>
+#ifdef _ALLBSD_SOURCE
+#include <sys/wait.h>
+#else
 #include <wait.h>
+#endif
 #include <signal.h>
 #include <string.h>
 #include <errno.h>
@@ -49,6 +53,17 @@
 #include <fcntl.h>
 #include <limits.h>
 
+#ifdef __FreeBSD__
+#include <dlfcn.h>
+#include <pthread.h>
+#include <pthread_np.h>
+#endif
+
+#ifdef __APPLE__
+#include <crt_externs.h>
+#define environ (*_NSGetEnviron())
+#endif
+
 /*
  * There are 3 possible strategies we might use to "fork":
  *
@@ -385,9 +400,35 @@ isAsciiDigit(char c)
   return c >= '0' && c <= '9';
 }
 
+#if defined(__OpenBSD__)
+/*
+ * Directly call _thread_sys_closefrom() so the child process
+ * doesn't reset the parrent's file descriptors to be blocking.
+ * This function is only called from the child process which
+ * is single threaded and about to call execvp() so it is
+ * safe to bypass the threaded closefrom().
+ */
+int _thread_sys_closefrom(int);
+
 static int
 closeDescriptors(void)
 {
+  return _thread_sys_closefrom(FAIL_FILENO + 1);
+}
+
+#else
+
+#ifdef _ALLBSD_SOURCE
+#define FD_DIR "/dev/fd"
+#define dirent64 dirent
+#define readdir64 readdir
+#else
+#define FD_DIR "/proc/self/fd"
+#endif
+
+static int
+closeDescriptors(void)
+{
     DIR *dp;
     struct dirent64 *dirp;
     int from_fd = FAIL_FILENO + 1;
@@ -402,7 +443,7 @@ closeDescriptors(void)
     restartableClose(from_fd);          /* for possible use by opendir() */
     restartableClose(from_fd + 1);      /* another one for good luck */
 
-    if ((dp = opendir("/proc/self/fd")) == NULL)
+    if ((dp = opendir(FD_DIR)) == NULL)
         return 0;
 
     /* We use readdir64 instead of readdir to work around Solaris bug
@@ -419,6 +460,7 @@ closeDescriptors(void)
 
     return 1;
 }
+#endif /* !__OpenBSD__ */
 
 static int
 moveDescriptor(int fd_from, int fd_to)
@@ -556,6 +598,21 @@ JDK_execvpe(const char *file,
             const char *argv[],
             const char *const envp[])
 {
+    /* This is one of the rare times it's more portable to declare an
+     * external symbol explicitly, rather than via a system header.
+     * The declaration is standardized as part of UNIX98, but there is
+     * no standard (not even de-facto) header file where the
+     * declaration is to be found.  See:
+     * http://www.opengroup.org/onlinepubs/009695399/functions/environ.html
+     * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html
+     *
+     * "All identifiers in this volume of IEEE Std 1003.1-2001, except
+     * environ, are defined in at least one of the headers" (!)
+     */
+#ifndef __APPLE__
+    extern char **environ;
+#endif
+
     if (envp == NULL || (char **) envp == environ) {
         execvp(file, (char **) argv);
         return;
