aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Herbert Valerio Riedel <hvr@gnu.org>2014-12-06 15:39:12 +0100
committerGravatar Herbert Valerio Riedel <hvr@gnu.org>2014-12-06 15:47:36 +0100
commitf24ba78f68b2cbc4f4afadc8dd60fc2935357255 (patch)
treef0f82b0a48222905cf12da233c5b5b3eb2392cac
parent123fcba7125c3b94ad35c3d7dfe31c715a79a470 (diff)
Refactor local `execvpe(3)` implementation
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)`)
-rw-r--r--System/Posix/Process/Internals.hs2
-rw-r--r--cbits/execvpe.c44
-rw-r--r--cbits/ghcrts.c14
-rw-r--r--configure.ac3
-rw-r--r--include/execvpe.h24
-rw-r--r--unix.cabal1
6 files changed, 44 insertions, 44 deletions
diff --git a/System/Posix/Process/Internals.hs b/System/Posix/Process/Internals.hs
index bd3dd31..b320dc7 100644
--- a/System/Posix/Process/Internals.hs
+++ b/System/Posix/Process/Internals.hs
@@ -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
diff --git a/cbits/execvpe.c b/cbits/execvpe.c
index 6ce1e9d..8c9d52d 100644
--- a/cbits/execvpe.c
+++ b/cbits/execvpe.c
@@ -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>
@@ -59,8 +65,11 @@
*/
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
index 0000000..1e0dc1c
--- /dev/null
+++ b/cbits/ghcrts.c
@@ -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
+}
diff --git a/configure.ac b/configure.ac
index f519d19..cf5a1fd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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])
diff --git a/include/execvpe.h b/include/execvpe.h
index c3b2dd3..1d49e35 100644
--- a/include/execvpe.h
+++ b/include/execvpe.h
@@ -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
-
diff --git a/unix.cabal b/unix.cabal
index ddd95de..69470ba 100644
--- a/unix.cabal
+++ b/unix.cabal
@@ -127,3 +127,4 @@ library
cbits/HsUnix.c
cbits/dirUtils.c
cbits/execvpe.c
+ cbits/ghcrts.c