summaryrefslogtreecommitdiff
path: root/libc/unistd/execl.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/unistd/execl.c')
-rw-r--r--libc/unistd/execl.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/libc/unistd/execl.c b/libc/unistd/execl.c
new file mode 100644
index 000000000..531c2ee60
--- /dev/null
+++ b/libc/unistd/execl.c
@@ -0,0 +1,51 @@
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+extern char **environ;
+
+int execl(__const char *path, __const char *arg, ...)
+{
+ const char *shortargv[16];
+ const char **argv;
+ const char *c;
+ int i;
+ va_list args;
+
+ i = 1;
+
+ va_start(args, arg);
+
+ do {
+ c = va_arg(args, const char *);
+
+ i++;
+ } while (c);
+
+ va_end(args);
+
+ if (i <= 16)
+ argv = shortargv;
+ else {
+ argv = (const char **) malloc(sizeof(char *) * i);
+ }
+
+ argv[0] = arg;
+ i = 1;
+
+ va_start(args, arg);
+
+ do {
+ argv[i] = va_arg(args, const char *);
+ } while (argv[i++]);
+
+ va_end(args);
+
+ i = execve(path, (char *const *) argv, environ);
+
+ if (argv != shortargv)
+ free(argv);
+
+ return i;
+}