From 123d11e4e37094f350bb377398d61e29eda60b13 Mon Sep 17 00:00:00 2001 From: EnderIce2 Date: Thu, 20 Feb 2025 02:07:04 +0200 Subject: [PATCH] feat(userspace/libc): implement system() function Signed-off-by: EnderIce2 --- Userspace/libc/include/stdlib.h | 2 +- Userspace/libc/src/std/stdlib.c | 51 ++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/Userspace/libc/include/stdlib.h b/Userspace/libc/include/stdlib.h index 72423123..fb156d9f 100644 --- a/Userspace/libc/include/stdlib.h +++ b/Userspace/libc/include/stdlib.h @@ -103,7 +103,7 @@ extern "C" long strtol(const char *restrict nptr, char **restrict endptr, int base); long long strtoll(const char *restrict nptr, char **restrict endptr, int base); unsigned long int strtoul(const char *, char **, int); - int system(const char *); + int system(const char *command); int ttyslot(void); int unlockpt(int); void *valloc(size_t); diff --git a/Userspace/libc/src/std/stdlib.c b/Userspace/libc/src/std/stdlib.c index 2d9a643e..ef80e9fc 100644 --- a/Userspace/libc/src/std/stdlib.c +++ b/Userspace/libc/src/std/stdlib.c @@ -330,7 +330,56 @@ export long long strtoll(const char *restrict nptr, char **restrict endptr, int } export unsigned long int strtoul(const char *, char **, int); -export int system(const char *); + +export int system(const char *command) +{ + if (command == NULL) + return 1; + + pid_t pid; + int status; + struct sigaction sa, old_int, old_quit; + sigset_t new_mask, old_mask; + + sa.sa_handler = SIG_IGN; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGINT, &sa, &old_int); + sigaction(SIGQUIT, &sa, &old_quit); + + sigemptyset(&new_mask); + sigaddset(&new_mask, SIGCHLD); + sigprocmask(SIG_BLOCK, &new_mask, &old_mask); + + if ((pid = fork()) == 0) + { + sigaction(SIGINT, &old_int, NULL); + sigaction(SIGQUIT, &old_quit, NULL); + sigprocmask(SIG_SETMASK, &old_mask, NULL); + execl("/bin/sh", "sh", "-c", command, (char *)0); + _exit(127); + } + + if (pid == -1) + status = -1; + else + { + while (waitpid(pid, &status, 0) == -1) + { + if (errno != EINTR) + { + status = -1; + break; + } + } + } + + sigaction(SIGINT, &old_int, NULL); + sigaction(SIGQUIT, &old_quit, NULL); + sigprocmask(SIG_SETMASK, &old_mask, NULL); + return status; +} + export int ttyslot(void); export int unlockpt(int); export void *valloc(size_t);