Refactor local `execvpe(3)` implementation
authorHerbert Valerio Riedel <hvr@gnu.org>
Sat, 6 Dec 2014 14:39:12 +0000 (15:39 +0100)
committerHerbert Valerio Riedel <hvr@gnu.org>
Sat, 6 Dec 2014 14:47:36 +0000 (15:47 +0100)
The previous code was prone to conflicts with when the platform happens
to expose a `execvpe(3)` implementation in its libc.

This commit renames the internal implementation to `__hsunix_execvpe` as
well as adding an autoconf-detection for the presence of `execvpe(3)`,
in which case `__hsunix_execvpe()` forwards the call to `execvpe(3)`.

Moreover, the code has been cleaned up to remove likely bitrotted CPP
conditionals.

This should fix #22

(This also partially addresses #11 on platforms which have a
libc-provided `execvpe(3)`)

System/Posix/Process/Internals.hs
cbits/execvpe.c
cbits/ghcrts.c [new file with mode: 0644]
configure.ac
include/execvpe.h
unix.cabal

index bd3dd31..b320dc7 100644 (file)
@@ -30,7 +30,7 @@ data ProcessStatus
 foreign import ccall unsafe "pPrPr_disableITimers"
   pPrPr_disableITimers :: IO ()
 
-foreign import ccall unsafe "execvpe"
+foreign import ccall unsafe "__hsunix_execvpe"
   c_execvpe :: CString -> Ptr CString -> Ptr CString -> IO CInt
 
 decipherWaitStatus :: CInt -> IO ProcessStatus
index 6ce1e9d..8c9d52d 100644 (file)
@@ -2,19 +2,25 @@
    (c) The University of Glasgow 1995-2004
 
    Our low-level exec() variant.
+
+   Note: __hsunix_execvpe() is very similiar to the function
+         execvpe(3) as provided by glibc 2.11 and later. However, if
+         execvpe(3) is available, we use that instead.
+
    -------------------------------------------------------------------------- */
 #include "execvpe.h"
 
-#ifdef __GLASGOW_HASKELL__
-#include "Rts.h"
-#endif
+#include "HsUnixConfig.h"
 
-#if !(defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)) /* to the end */
-#ifndef __QNXNTO__
-
-/* Evidently non-Posix. */
-/* #include "PosixSource.h" */
+#if HAVE_EXECVPE
+# define _GNU_SOURCE
+#endif
 
+#include <errno.h>
+#include <sys/types.h>
+#if HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
 #include <unistd.h>
 #include <sys/time.h>
 #include <stdlib.h>
  */
 
 int
-execvpe(char *name, char *const argv[], char **envp)
+__hsunix_execvpe(const char *name, char *const argv[], char *const envp[])
 {
+#if HAVE_EXECVPE
+    return execvpe(name, argv, envp);
+#else
     register int lp, ln;
     register char *p;
     int eacces=0, etxtbsy=0;
@@ -75,18 +84,18 @@ execvpe(char *name, char *const argv[], char **envp)
 
     /* Get the path we're searching. */
     if (!(path = getenv("PATH"))) {
-#ifdef HAVE_CONFSTR
+# ifdef HAVE_CONFSTR
         ln = confstr(_CS_PATH, NULL, 0);
         if ((cur = path = malloc(ln + 1)) != NULL) {
            path[0] = ':';
            (void) confstr (_CS_PATH, path + 1, ln);
        }
-#else
+# else
         if ((cur = path = malloc(1 + 1)) != NULL) {
            path[0] = ':';
            path[1] = '\0';
        }
-#endif
+# endif
     } else
        cur = path = strdup(path);
 
@@ -157,16 +166,5 @@ execvpe(char *name, char *const argv[], char **envp)
     if (buf)
        free(buf);
     return (-1);
-}
-#endif
-
-
-/* Copied verbatim from ghc/lib/std/cbits/system.c. */
-void pPrPr_disableITimers (void)
-{
-#ifdef __GLASGOW_HASKELL__
-    stopTimer();
 #endif
 }
-
-#endif
diff --git a/cbits/ghcrts.c b/cbits/ghcrts.c
new file mode 100644 (file)
index 0000000..1e0dc1c
--- /dev/null
@@ -0,0 +1,14 @@
+#include "execvpe.h"
+
+#ifdef __GLASGOW_HASKELL__
+// for 'void StopTimer(void)' prototype
+# include "Rts.h"
+#endif
+
+/* Copied verbatim from ghc/lib/std/cbits/system.c. */
+void pPrPr_disableITimers (void)
+{
+#ifdef __GLASGOW_HASKELL__
+    stopTimer();
+#endif
+}
index f519d19..cf5a1fd 100644 (file)
@@ -39,6 +39,9 @@ AC_CHECK_FUNCS([readdir_r])
 dnl not available on android so check for it
 AC_CHECK_FUNCS([telldir seekdir])
 
+dnl This is e.g. available as a GNU extension in glibc 2.11+
+AC_CHECK_FUNCS([execvpe])
+
 AC_CHECK_MEMBERS([struct stat.st_atim])
 AC_CHECK_MEMBERS([struct stat.st_mtim])
 AC_CHECK_MEMBERS([struct stat.st_ctim])
index c3b2dd3..1d49e35 100644 (file)
@@ -1,27 +1,11 @@
 /* ----------------------------------------------------------------------------
    (c) The University of Glasgow 2004
 
-   Interface for code in execvpe.c
+   Interface for code in cbits/execvpe.c
    ------------------------------------------------------------------------- */
 
-#include "HsUnixConfig.h"
-// Otherwise these clash with similar definitions from other packages:
-#undef PACKAGE_BUGREPORT
-#undef PACKAGE_NAME
-#undef PACKAGE_STRING
-#undef PACKAGE_TARNAME
-#undef PACKAGE_VERSION
+extern int
+__hsunix_execvpe(const char *name, char *const argv[], char *const envp[]);
 
-#include <errno.h>
-#include <sys/types.h>
-#if HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-
-#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_WIN32)
-#ifndef __QNXNTO__
-extern int execvpe(char *name, char *const argv[], char **envp);
-#endif
+// implemented in cbits/ghcrts.c
 extern void pPrPr_disableITimers (void);
-#endif
-
index ddd95de..69470ba 100644 (file)
@@ -127,3 +127,4 @@ library
         cbits/HsUnix.c
         cbits/dirUtils.c
         cbits/execvpe.c
+        cbits/ghcrts.c