diff --git a/Cargo.lock b/Cargo.lock index 9d00bc78ed..d1ff18f5a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -435,6 +435,7 @@ dependencies = [ "rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "string 0.1.0", "time 0.1.0", + "unistd 0.1.0", "wchar 0.1.0", ] diff --git a/src/stdlib/Cargo.toml b/src/stdlib/Cargo.toml index 8da566d362..5a79260722 100644 --- a/src/stdlib/Cargo.toml +++ b/src/stdlib/Cargo.toml @@ -12,6 +12,7 @@ platform = { path = "../platform" } ctype = { path = "../ctype" } errno = { path = "../errno" } rand = { version = "0.5.2", default-features = false } -time = { path = "../time" } -wchar = { path = "../wchar" } string = { path = "../string" } +time = { path = "../time" } +unistd = { path = "../unistd" } +wchar = { path = "../wchar" } diff --git a/src/stdlib/src/lib.rs b/src/stdlib/src/lib.rs index 1afe2638e9..52a1bab517 100644 --- a/src/stdlib/src/lib.rs +++ b/src/stdlib/src/lib.rs @@ -9,6 +9,7 @@ extern crate platform; extern crate rand; extern crate string; extern crate time; +extern crate unistd; extern crate wchar; use core::{ptr, str}; @@ -783,8 +784,37 @@ pub unsafe extern "C" fn strtol(s: *const c_char, endptr: *mut *mut c_char, base } #[no_mangle] -pub extern "C" fn system(command: *const c_char) -> c_int { - unimplemented!(); +pub unsafe extern "C" fn system(command: *const c_char) -> c_int { + let child_pid = unistd::fork(); + if child_pid == 0 { + let command_nonnull = if command.is_null() { + "exit 0\0".as_ptr() + } else { + command as *const u8 + }; + + let shell = "/bin/sh\0".as_ptr(); + + let args = [ + "sh\0".as_ptr(), + "-c\0".as_ptr(), + command_nonnull, + ptr::null() + ]; + + unistd::execv(shell as *const c_char, args.as_ptr() as *const *mut c_char); + + exit(127); + + unreachable!(); + } else { + let mut wstatus = 0; + if platform::waitpid(child_pid, &mut wstatus, 0) < 0 { + return -1; + } + + wstatus + } } #[no_mangle] diff --git a/tests/.gitignore b/tests/.gitignore index afb0d2f8cf..3fb46de657 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,65 +1,66 @@ +# Automatically generated by 'make ignore' /*.out /gen/ -/alloc -/assert -/args -/atof -/atoi -/brk -/chdir -/create -/ctype -/dup -/error -/exec -/fchdir -/fcntl -/fsync -/ftruncate -/getc_unget -/gethostname -/getid -/link -/locale -/math -/mem -/pipe -/printf -/rmdir -/rename -/scanf -/setid -/setjmp -/sleep -/sprintf -/strings -/stdlib/a64l -/stdlib/bsearch -/stdlib/mktemp -/stdlib/rand -/stdlib/strtol -/stdlib/strtoul -/stdlib/a64l -/stdio/fwrite -/stdio/all -/stdio/freopen -/string/strchr -/string/strcspn -/string/strncmp -/string/strpbrk -/string/strrchr -/string/strspn -/string/strstr -/string/strtok -/string/strtok_r -/unistd/getopt -/unlink -/waitpid -/wchar/mbrtowc -/wchar/mbsrtowcs -/wchar/putwchar -/wchar/wcrtomb -/write -/time -/gmtime -/asctime +assert +atof +atoi +brk +args +create +ctype +dup +error +exec +fchdir +fcntl +fsync +ftruncate +getc_unget +locale +math +mem +pipe +printf +rename +rmdir +scanf +setjmp +sleep +sprintf +strings +stdio/fwrite +stdio/all +stdio/freopen +stdlib/strtol +stdlib/strtoul +stdlib/a64l +stdlib/rand +string/strncmp +string/strcspn +string/strchr +string/strrchr +string/strspn +string/strstr +string/strpbrk +string/strtok +string/strtok_r +system +unistd/getopt +waitpid +wchar/mbrtowc +wchar/mbsrtowcs +wchar/putwchar +wchar/wcrtomb +write +time +gmtime +asctime +alloc +chdir +gethostname +getid +link +setid +stdlib/bsearch +stdlib/mktemp +unlink diff --git a/tests/Makefile b/tests/Makefile index 0957b27f2c..3584543252 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -43,6 +43,7 @@ EXPECT_BINS=\ string/strpbrk \ string/strtok \ string/strtok_r \ + system \ unistd/getopt \ waitpid \ wchar/mbrtowc \ @@ -72,6 +73,15 @@ all: $(BINS) clean: rm -f $(BINS) *.out +ignore: $(BINS) + echo "# Automatically generated by 'make ignore'" > .gitignore + echo "/*.out" >> .gitignore + echo "/gen/" >> .gitignore + for bin in $^; \ + do \ + echo "$${bin}" >> .gitignore; \ + done + run: $(BINS) for bin in $^; \ do \ diff --git a/tests/expected/system.stderr b/tests/expected/system.stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/expected/system.stdout b/tests/expected/system.stdout new file mode 100644 index 0000000000..a6d3f18a28 --- /dev/null +++ b/tests/expected/system.stdout @@ -0,0 +1 @@ +test of system diff --git a/tests/system.c b/tests/system.c new file mode 100644 index 0000000000..8c4cda187c --- /dev/null +++ b/tests/system.c @@ -0,0 +1,6 @@ +#include + +int main(int argc, char ** argv) { + system("echo test of system"); + return 0; +}