summaryrefslogtreecommitdiff
path: root/lib/libc/unistd/execvp.c
diff options
context:
space:
mode:
authorKacper <kacper@mail.openlinux.dev>2025-12-07 20:10:31 +0100
committerKacper <kacper@mail.openlinux.dev>2025-12-07 20:10:31 +0100
commitfc00c656c96528112d05cf0edf8631bd5eaea446 (patch)
treea6e0e6c588191a8bd1c64afc3b7a258e3e66c236 /lib/libc/unistd/execvp.c
Add build system scaffolding and libc headers
Diffstat (limited to 'lib/libc/unistd/execvp.c')
-rw-r--r--lib/libc/unistd/execvp.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/lib/libc/unistd/execvp.c b/lib/libc/unistd/execvp.c
new file mode 100644
index 00000000..2ce69354
--- /dev/null
+++ b/lib/libc/unistd/execvp.c
@@ -0,0 +1,55 @@
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+
+extern char **environ;
+
+int execvp(const char *file, char *const argv[])
+{
+ if (*file == '\0') {
+ errno = ENOENT;
+ return -1;
+ }
+
+ if (strchr(file, '/') != NULL) {
+ return execv(file, argv);
+ } else {
+ char *ptr;
+ char *path = NULL; // TODO: getenv
+
+ if (path == NULL || *path == '\0') {
+ path = "/bin";
+ }
+
+ do {
+ char buf[PATH_MAX];
+
+ if ((ptr = strchr(path, ':')) == NULL) {
+ if (snprintf(buf, PATH_MAX, "%s/%s", path,
+ file) >= PATH_MAX) {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
+ execv(buf, argv);
+ break;
+ }
+
+ if (snprintf(buf, PATH_MAX, "%.*s/%s",
+ (int)(ptr - path), path,
+ file) >= PATH_MAX) {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
+ execv(buf, argv);
+ } while (*ptr != '\0');
+
+ errno = ENOENT;
+ return -1;
+ }
+
+ return 0;
+}