summaryrefslogtreecommitdiff
path: root/libc/misc/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/misc/system.c')
-rw-r--r--libc/misc/system.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/libc/misc/system.c b/libc/misc/system.c
new file mode 100644
index 0000000..f48f68d
--- /dev/null
+++ b/libc/misc/system.c
@@ -0,0 +1,49 @@
+
+#include <stddef.h>
+#include <signal.h>
+
+int
+system(command)
+char * command;
+{
+ int wait_val, wait_ret, pid;
+ __sighandler_t save_quit;
+ __sighandler_t save_int;
+
+ if( command == 0 ) return 1;
+
+ save_quit = signal(SIGQUIT, SIG_IGN);
+ save_int = signal(SIGINT, SIG_IGN);
+
+ if( (pid=vfork()) < 0 )
+ {
+ signal(SIGQUIT, save_quit);
+ signal(SIGINT, save_int);
+ return -1;
+ }
+ if( pid == 0 )
+ {
+ signal(SIGQUIT, SIG_DFL);
+ signal(SIGINT, SIG_DFL);
+
+ execl("/bin/sh", "sh", "-c", command, (char*)0);
+ _exit(127);
+ }
+ /* Signals are not absolutly guarenteed with vfork */
+ signal(SIGQUIT, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
+
+ do
+ {
+ if( (wait_ret = wait(&wait_val)) == -1 )
+ {
+ wait_val = -1;
+ break;
+ }
+ }
+ while( wait_ret != pid );
+
+ signal(SIGQUIT, save_quit);
+ signal(SIGINT, save_int);
+ return wait_val;
+}