Skip to content
Snippets Groups Projects
Commit f24ba78f authored by Herbert Valerio Riedel's avatar Herbert Valerio Riedel :man_dancing:
Browse files

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)`)
parent 123fcba7
No related branches found
No related tags found
No related merge requests found
...@@ -30,7 +30,7 @@ data ProcessStatus ...@@ -30,7 +30,7 @@ data ProcessStatus
foreign import ccall unsafe "pPrPr_disableITimers" foreign import ccall unsafe "pPrPr_disableITimers"
pPrPr_disableITimers :: IO () pPrPr_disableITimers :: IO ()
foreign import ccall unsafe "execvpe" foreign import ccall unsafe "__hsunix_execvpe"
c_execvpe :: CString -> Ptr CString -> Ptr CString -> IO CInt c_execvpe :: CString -> Ptr CString -> Ptr CString -> IO CInt
decipherWaitStatus :: CInt -> IO ProcessStatus decipherWaitStatus :: CInt -> IO ProcessStatus
......
...@@ -2,19 +2,25 @@ ...@@ -2,19 +2,25 @@
(c) The University of Glasgow 1995-2004 (c) The University of Glasgow 1995-2004
Our low-level exec() variant. 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" #include "execvpe.h"
#ifdef __GLASGOW_HASKELL__ #include "HsUnixConfig.h"
#include "Rts.h"
#endif
#if !(defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)) /* to the end */ #if HAVE_EXECVPE
#ifndef __QNXNTO__ # define _GNU_SOURCE
#endif
/* Evidently non-Posix. */
/* #include "PosixSource.h" */
#include <errno.h>
#include <sys/types.h>
#if HAVE_SYS_WAIT_H
# include <sys/wait.h>
#endif
#include <unistd.h> #include <unistd.h>
#include <sys/time.h> #include <sys/time.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -59,8 +65,11 @@ ...@@ -59,8 +65,11 @@
*/ */
int 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 int lp, ln;
register char *p; register char *p;
int eacces=0, etxtbsy=0; int eacces=0, etxtbsy=0;
...@@ -75,18 +84,18 @@ execvpe(char *name, char *const argv[], char **envp) ...@@ -75,18 +84,18 @@ execvpe(char *name, char *const argv[], char **envp)
/* Get the path we're searching. */ /* Get the path we're searching. */
if (!(path = getenv("PATH"))) { if (!(path = getenv("PATH"))) {
#ifdef HAVE_CONFSTR # ifdef HAVE_CONFSTR
ln = confstr(_CS_PATH, NULL, 0); ln = confstr(_CS_PATH, NULL, 0);
if ((cur = path = malloc(ln + 1)) != NULL) { if ((cur = path = malloc(ln + 1)) != NULL) {
path[0] = ':'; path[0] = ':';
(void) confstr (_CS_PATH, path + 1, ln); (void) confstr (_CS_PATH, path + 1, ln);
} }
#else # else
if ((cur = path = malloc(1 + 1)) != NULL) { if ((cur = path = malloc(1 + 1)) != NULL) {
path[0] = ':'; path[0] = ':';
path[1] = '\0'; path[1] = '\0';
} }
#endif # endif
} else } else
cur = path = strdup(path); cur = path = strdup(path);
...@@ -157,16 +166,5 @@ execvpe(char *name, char *const argv[], char **envp) ...@@ -157,16 +166,5 @@ execvpe(char *name, char *const argv[], char **envp)
if (buf) if (buf)
free(buf); free(buf);
return (-1); return (-1);
}
#endif
/* Copied verbatim from ghc/lib/std/cbits/system.c. */
void pPrPr_disableITimers (void)
{
#ifdef __GLASGOW_HASKELL__
stopTimer();
#endif #endif
} }
#endif
#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
}
...@@ -39,6 +39,9 @@ AC_CHECK_FUNCS([readdir_r]) ...@@ -39,6 +39,9 @@ AC_CHECK_FUNCS([readdir_r])
dnl not available on android so check for it dnl not available on android so check for it
AC_CHECK_FUNCS([telldir seekdir]) 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_atim])
AC_CHECK_MEMBERS([struct stat.st_mtim]) AC_CHECK_MEMBERS([struct stat.st_mtim])
AC_CHECK_MEMBERS([struct stat.st_ctim]) AC_CHECK_MEMBERS([struct stat.st_ctim])
......
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
(c) The University of Glasgow 2004 (c) The University of Glasgow 2004
Interface for code in execvpe.c Interface for code in cbits/execvpe.c
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
#include "HsUnixConfig.h" extern int
// Otherwise these clash with similar definitions from other packages: __hsunix_execvpe(const char *name, char *const argv[], char *const envp[]);
#undef PACKAGE_BUGREPORT
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
#include <errno.h> // implemented in cbits/ghcrts.c
#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
extern void pPrPr_disableITimers (void); extern void pPrPr_disableITimers (void);
#endif
...@@ -127,3 +127,4 @@ library ...@@ -127,3 +127,4 @@ library
cbits/HsUnix.c cbits/HsUnix.c
cbits/dirUtils.c cbits/dirUtils.c
cbits/execvpe.c cbits/execvpe.c
cbits/ghcrts.c
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment