summaryrefslogtreecommitdiff
path: root/src/process
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011-02-12 00:22:29 -0500
committerRich Felker <dalias@aerifal.cx>2011-02-12 00:22:29 -0500
commit0b44a0315b47dd8eced9f3b7f31580cf14bbfc01 (patch)
tree6eaef0d8a720fa3da580de87b647fff796fe80b3 /src/process
downloadmusl-0b44a0315b47dd8eced9f3b7f31580cf14bbfc01.tar.gz
initial check-in, version 0.5.0v0.5.0
Diffstat (limited to 'src/process')
-rw-r--r--src/process/execl.c20
-rw-r--r--src/process/execle.c22
-rw-r--r--src/process/execlp.c20
-rw-r--r--src/process/execv.c8
-rw-r--r--src/process/execve.c8
-rw-r--r--src/process/execvp.c34
-rw-r--r--src/process/fork.c9
-rw-r--r--src/process/system.c45
-rw-r--r--src/process/vfork.c8
-rw-r--r--src/process/wait.c6
-rw-r--r--src/process/waitid.c7
-rw-r--r--src/process/waitpid.c7
12 files changed, 194 insertions, 0 deletions
diff --git a/src/process/execl.c b/src/process/execl.c
new file mode 100644
index 00000000..4c6eaa94
--- /dev/null
+++ b/src/process/execl.c
@@ -0,0 +1,20 @@
+#include <unistd.h>
+#include <stdarg.h>
+
+int execl(const char *path, ...)
+{
+ int argc;
+ va_list ap;
+ va_start(ap, path);
+ for (argc=0; va_arg(ap, const char *); argc++);
+ va_end(ap);
+ {
+ int i;
+ char *argv[argc+1];
+ va_start(ap, path);
+ for (i=0; i<argc; i++)
+ argv[i] = va_arg(ap, char *);
+ argv[i] = NULL;
+ return execv(path, argv);
+ }
+}
diff --git a/src/process/execle.c b/src/process/execle.c
new file mode 100644
index 00000000..37f629d9
--- /dev/null
+++ b/src/process/execle.c
@@ -0,0 +1,22 @@
+#include <unistd.h>
+#include <stdarg.h>
+
+int execle(const char *path, ...)
+{
+ int argc;
+ va_list ap;
+ va_start(ap, path);
+ for (argc=0; va_arg(ap, const char *); argc++);
+ va_end(ap);
+ {
+ int i;
+ char *argv[argc+1];
+ char **envp;
+ va_start(ap, path);
+ for (i=0; i<argc; i++)
+ argv[i] = va_arg(ap, char *);
+ argv[i] = NULL;
+ envp = va_arg(ap, char **);
+ return execve(path, argv, envp);
+ }
+}
diff --git a/src/process/execlp.c b/src/process/execlp.c
new file mode 100644
index 00000000..33fb0f7f
--- /dev/null
+++ b/src/process/execlp.c
@@ -0,0 +1,20 @@
+#include <unistd.h>
+#include <stdarg.h>
+
+int execlp(const char *file, ...)
+{
+ int argc;
+ va_list ap;
+ va_start(ap, file);
+ for (argc=0; va_arg(ap, const char *); argc++);
+ va_end(ap);
+ {
+ int i;
+ char *argv[argc+1];
+ va_start(ap, file);
+ for (i=0; i<argc; i++)
+ argv[i] = va_arg(ap, char *);
+ argv[i] = NULL;
+ return execvp(file, argv);
+ }
+}
diff --git a/src/process/execv.c b/src/process/execv.c
new file mode 100644
index 00000000..2ac0dec0
--- /dev/null
+++ b/src/process/execv.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+
+extern char **__environ;
+
+int execv(const char *path, char *const argv[])
+{
+ return execve(path, argv, __environ);
+}
diff --git a/src/process/execve.c b/src/process/execve.c
new file mode 100644
index 00000000..2a0b62d6
--- /dev/null
+++ b/src/process/execve.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int execve(const char *path, char *const argv[], char *const envp[])
+{
+ /* do we need to use environ if envp is null? */
+ return syscall3(__NR_execve, (long)path, (long)argv, (long)envp);
+}
diff --git a/src/process/execvp.c b/src/process/execvp.c
new file mode 100644
index 00000000..d799ddae
--- /dev/null
+++ b/src/process/execvp.c
@@ -0,0 +1,34 @@
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+extern char **__environ;
+
+int execvp(const char *file, char *const argv[])
+{
+ const char *p, *z, *path = getenv("PATH");
+ int l;
+
+ if (strchr(file, '/'))
+ return execve(file, argv, __environ);
+
+ /* FIXME: integer overflows */
+ if (!path) path = "/usr/local/bin:/bin:/usr/bin";
+ l = strlen(file) + strlen(path) + 2;
+
+ for(p=path; p && *p; p=z) {
+ char b[l];
+ z = strchr(p, ':');
+ if (z) {
+ memcpy(b, p, z-p);
+ b[z++-p] = 0;
+ } else strcpy(b, p);
+ strcat(b, "/");
+ strcat(b, file);
+ if (!access(b, X_OK))
+ return execve(b, argv, __environ);
+ }
+ errno = ENOENT;
+ return -1;
+}
diff --git a/src/process/fork.c b/src/process/fork.c
new file mode 100644
index 00000000..1213f0f5
--- /dev/null
+++ b/src/process/fork.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include "syscall.h"
+
+/* FIXME: add support for atfork stupidity */
+
+pid_t fork(void)
+{
+ return syscall0(__NR_fork);
+}
diff --git a/src/process/system.c b/src/process/system.c
new file mode 100644
index 00000000..0f1c07b5
--- /dev/null
+++ b/src/process/system.c
@@ -0,0 +1,45 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+int system(const char *cmd)
+{
+ pid_t pid;
+ sigset_t old, new;
+ struct sigaction sa, oldint, oldquit;
+ int status;
+
+ if (!cmd) return 1;
+
+ sa.sa_handler = SIG_IGN;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+
+ sigaction(SIGINT, &sa, &oldint);
+ sigaction(SIGQUIT, &sa, &oldquit);
+ sigaddset(&sa.sa_mask, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &new, &old);
+
+ pid = fork();
+ if (pid <= 0) {
+ sigaction(SIGINT, &oldint, NULL);
+ sigaction(SIGQUIT, &oldquit, NULL);
+ sigprocmask(SIG_SETMASK, &old, NULL);
+ if (pid == 0) {
+ execl("/bin/sh", "sh", "-c", cmd, (char *)0);
+ _exit(127);
+ }
+ return -1;
+ }
+ while (waitpid(pid, &status, 0) == -1)
+ if (errno != EINTR) {
+ status = -1;
+ break;
+ }
+ sigaction(SIGINT, &oldint, NULL);
+ sigaction(SIGQUIT, &oldquit, NULL);
+ sigprocmask(SIG_SETMASK, &old, NULL);
+ return status;
+}
diff --git a/src/process/vfork.c b/src/process/vfork.c
new file mode 100644
index 00000000..32a7a6ed
--- /dev/null
+++ b/src/process/vfork.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t vfork(void)
+{
+ /* vfork syscall cannot be made from C code */
+ return syscall0(__NR_fork);
+}
diff --git a/src/process/wait.c b/src/process/wait.c
new file mode 100644
index 00000000..34da102d
--- /dev/null
+++ b/src/process/wait.c
@@ -0,0 +1,6 @@
+#include <sys/wait.h>
+
+pid_t wait(int *status)
+{
+ return waitpid((pid_t)-1, status, 0);
+}
diff --git a/src/process/waitid.c b/src/process/waitid.c
new file mode 100644
index 00000000..0ec0d55c
--- /dev/null
+++ b/src/process/waitid.c
@@ -0,0 +1,7 @@
+#include <sys/wait.h>
+#include "syscall.h"
+
+int waitid(idtype_t type, id_t id, siginfo_t *info, int options)
+{
+ return syscall5(__NR_waitid, type, id, (long)info, options, 0);
+}
diff --git a/src/process/waitpid.c b/src/process/waitpid.c
new file mode 100644
index 00000000..0ddcd15a
--- /dev/null
+++ b/src/process/waitpid.c
@@ -0,0 +1,7 @@
+#include <sys/wait.h>
+#include "syscall.h"
+
+pid_t waitpid(pid_t pid, int *status, int options)
+{
+ return syscall4(__NR_wait4, pid, (long)status, options, 0);
+}