diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index 9393eedd..799fbc1c 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -100,7 +100,8 @@ extern "C" /* Exit the program abnormally, without performing any registered cleanup actions. */ __noreturn void _Exit(int status); - int system(const char*); + /* Execute a shell command. */ + int system(const char* cmd); /* Get the value of an environment variable. */ char* getenv(const char* key); diff --git a/libc/include/sys/wait.h b/libc/include/sys/wait.h index 71cf0798..4fa9c3e5 100644 --- a/libc/include/sys/wait.h +++ b/libc/include/sys/wait.h @@ -6,6 +6,9 @@ #include #include +#define WIFEXITED(ret) ((ret) | 0) +#define WEXITSTATUS(ret) ((ret)&0xff) + #ifdef __cplusplus extern "C" { diff --git a/libc/src/stdlib.cpp b/libc/src/stdlib.cpp index 9a6ea3cd..362f1a15 100644 --- a/libc/src/stdlib.cpp +++ b/libc/src/stdlib.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include template static inline ResultT __generic_div(ArgT a, ArgT b) @@ -175,4 +176,28 @@ extern "C" { free_impl(ptr); } + + int system(const char* cmd) + { + if (!cmd) + { + // FIXME: Check if there is a shell available in the system. + errno = ENOTSUP; + return -1; + } + + pid_t child = fork(); + if (child == 0) + { + execl("/bin/sh", "sh", "-c", cmd, NULL); + _Exit(127); + } + + if (child < 0) return -1; + + int status; + waitpid(child, &status, 0); + + return status; + } }