about summary refs log tree commit diff
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
musl-0b44a0315b47dd8eced9f3b7f31580cf14bbfc01.tar.xz
musl-0b44a0315b47dd8eced9f3b7f31580cf14bbfc01.zip
initial check-in, version 0.5.0 v0.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);
+}