From f24ba78f68b2cbc4f4afadc8dd60fc2935357255 Mon Sep 17 00:00:00 2001 From: Herbert Valerio Riedel Date: Sat, 6 Dec 2014 15:39:12 +0100 Subject: 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)`) --- System/Posix/Process/Internals.hs | 2 +- cbits/execvpe.c | 44 +++++++++++++++++++-------------------- cbits/ghcrts.c | 14 +++++++++++++ configure.ac | 3 +++ include/execvpe.h | 24 ++++----------------- unix.cabal | 1 + 6 files changed, 44 insertions(+), 44 deletions(-) create mode 100644 cbits/ghcrts.c 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 +#include +#if HAVE_SYS_WAIT_H +# include +#endif #include #include #include @@ -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 -#include -#if HAVE_SYS_WAIT_H -#include -#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 -- cgit v1.2.3