aboutsummaryrefslogtreecommitdiffstats
path: root/tools/llee/SysUtils.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llee/SysUtils.c')
-rw-r--r--tools/llee/SysUtils.c67
1 files changed, 52 insertions, 15 deletions
diff --git a/tools/llee/SysUtils.c b/tools/llee/SysUtils.c
index 8399612..6d6dc50 100644
--- a/tools/llee/SysUtils.c
+++ b/tools/llee/SysUtils.c
@@ -6,35 +6,46 @@
//===----------------------------------------------------------------------===//
#include "SysUtils.h"
-#include "Config/sys/types.h"
-#include "Config/sys/stat.h"
+#include "Config/dlfcn.h"
+#include "Config/errno.h"
#include "Config/fcntl.h"
-#include "Config/sys/wait.h"
#include "Config/unistd.h"
-#include "Config/errno.h"
+#include "Config/sys/stat.h"
+#include "Config/sys/types.h"
+#include "Config/sys/wait.h"
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
+ * isExecutable - This function returns true if given struct stat describes the
+ * file as being executable.
+ */
+unsigned isExecutable(const struct stat *buf) {
+ if (!(buf->st_mode & S_IFREG))
+ return 0; // Not a regular file?
+
+ if (buf->st_uid == getuid()) // Owner of file?
+ return buf->st_mode & S_IXUSR;
+ else if (buf->st_gid == getgid()) // In group of file?
+ return buf->st_mode & S_IXGRP;
+ else // Unrelated to file?
+ return buf->st_mode & S_IXOTH;
+}
+
+/*
* isExecutableFile - This function returns true if the filename specified
* exists and is executable.
*/
unsigned isExecutableFile(const char *ExeFileName) {
- struct stat Buf;
- if (stat(ExeFileName, &Buf))
+ struct stat buf;
+ if (stat(ExeFileName, &buf))
return 0; // Must not be executable!
- if (!(Buf.st_mode & S_IFREG))
- return 0; // Not a regular file?
-
- if (Buf.st_uid == getuid()) // Owner of file?
- return Buf.st_mode & S_IXUSR;
- else if (Buf.st_gid == getgid()) // In group of file?
- return Buf.st_mode & S_IXGRP;
- else // Unrelated to file?
- return Buf.st_mode & S_IXOTH;
+ return isExecutable(&buf);
}
+
/*
* FindExecutable - Find a named executable in the directories listed in $PATH.
* If the executable cannot be found, returns NULL.
@@ -81,3 +92,29 @@ char *FindExecutable(const char *ExeName) {
/* If we fell out, we ran out of directories to search, return failure. */
return NULL;
}
+
+/*
+ * The type of the execve() function is long and boring, but required.
+ */
+typedef int(*execveTy)(const char*, char *const[], char *const[]);
+
+/*
+ * This method finds the real `execve' call in the C library and executes the
+ * given program.
+ */
+int executeProgram(const char *filename, char *const argv[], char *const envp[])
+{
+ /*
+ * Find a pointer to the *real* execve() function starting the search in the
+ * next library and forward, to avoid finding the one defined in this file.
+ */
+ char *error;
+ execveTy execvePtr = (execveTy) dlsym(RTLD_NEXT, "execve");
+ if ((error = dlerror()) != NULL) {
+ fprintf(stderr, "%s\n", error);
+ return -1;
+ }
+
+ /* Really execute the program */
+ return execvePtr(filename, argv, envp);
+}