From ffd9176cdfe04694a25ec62f9b6a424e996e9e94 Mon Sep 17 00:00:00 2001 From: Paul Sajna Date: Wed, 7 Mar 2018 18:45:03 -0800 Subject: [PATCH 1/9] forgot to commit the makefile --- tests/.gitignore | 1 + tests/Makefile | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/.gitignore b/tests/.gitignore index 759d9904ee..dead47ff35 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -6,6 +6,7 @@ /create.out /dup /dup.out +/error /fchdir /fsync /ftruncate diff --git a/tests/Makefile b/tests/Makefile index 41dc224061..8d87af542c 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -5,6 +5,7 @@ BINS=\ chdir \ create \ dup \ + error \ fchdir \ fsync \ ftruncate \ From 3b7149612f329c5f38965970605203dd98199337 Mon Sep 17 00:00:00 2001 From: Paul Sajna Date: Wed, 7 Mar 2018 20:57:51 -0800 Subject: [PATCH 2/9] implement perror --- Cargo.lock | 1 + src/stdio/Cargo.toml | 1 + src/stdio/src/lib.rs | 15 ++++++++++++--- tests/error.c | 1 + 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c2ea9141fb..514bc4b615 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -445,6 +445,7 @@ version = "0.1.0" dependencies = [ "cbindgen 0.5.0", "platform 0.1.0", + "string 0.1.0", "va_list 0.1.0", ] diff --git a/src/stdio/Cargo.toml b/src/stdio/Cargo.toml index e64c0df1a5..dacf967fe2 100644 --- a/src/stdio/Cargo.toml +++ b/src/stdio/Cargo.toml @@ -10,3 +10,4 @@ cbindgen = { path = "../../cbindgen" } [dependencies] platform = { path = "../platform" } va_list = { path = "../../va_list", features = ["no_std"] } +string = { path = "../string" } diff --git a/src/stdio/src/lib.rs b/src/stdio/src/lib.rs index 05933a409a..696f752df6 100644 --- a/src/stdio/src/lib.rs +++ b/src/stdio/src/lib.rs @@ -4,10 +4,13 @@ extern crate platform; extern crate va_list as vl; +extern crate string; -use core::slice; +use core::str; +use core::fmt::Write; use platform::types::*; +use platform::c_str; use vl::VaList as va_list; mod printf; @@ -201,8 +204,14 @@ pub extern "C" fn pclose(stream: *mut FILE) -> c_int { } #[no_mangle] -pub extern "C" fn perror(s: *const c_char) { - unimplemented!(); +pub unsafe extern "C" fn perror(s: *const c_char) { + let strerror = string::strerror(platform::errno); + let mut w = platform::FileWriter(2); + w.write_fmt(format_args!( + "{}: {}\n", + str::from_utf8_unchecked(c_str(s)), + str::from_utf8_unchecked(c_str(strerror)) + )); } #[no_mangle] diff --git a/tests/error.c b/tests/error.c index 67fb25ed39..9ab04c2bd9 100644 --- a/tests/error.c +++ b/tests/error.c @@ -6,4 +6,5 @@ int main(int argc, char** argv) { chdir("nonexistent"); printf("errno: %d = %s\n", errno, strerror(errno)); + perror("perror"); } From 33f1033e0eb1a59049f941b35fc531d892cd3244 Mon Sep 17 00:00:00 2001 From: Paul Sajna Date: Wed, 7 Mar 2018 23:30:10 -0800 Subject: [PATCH 3/9] implement pipe and read --- src/platform/Cargo.toml | 3 +++ src/platform/src/lib.rs | 2 ++ src/platform/src/linux/mod.rs | 8 ++++++++ src/platform/src/redox/mod.rs | 15 +++++++++++++++ src/unistd/src/lib.rs | 6 ++++-- 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/platform/Cargo.toml b/src/platform/Cargo.toml index e25b8251c0..a00eb79be6 100644 --- a/src/platform/Cargo.toml +++ b/src/platform/Cargo.toml @@ -8,3 +8,6 @@ sc = "0.2" [target.'cfg(target_os = "redox")'.dependencies] redox_syscall = "0.1" + +[dependencies] +alloc-no-stdlib = "1.2" diff --git a/src/platform/src/lib.rs b/src/platform/src/lib.rs index a327053107..0506cdee4c 100644 --- a/src/platform/src/lib.rs +++ b/src/platform/src/lib.rs @@ -3,6 +3,8 @@ #![no_std] #![allow(non_camel_case_types)] //TODO #![feature(thread_local)] +#![feature(alloc)] +extern crate alloc; #[cfg(all(not(feature = "no_std"), target_os = "linux"))] #[macro_use] diff --git a/src/platform/src/linux/mod.rs b/src/platform/src/linux/mod.rs index a8d720939d..3f32ed2953 100644 --- a/src/platform/src/linux/mod.rs +++ b/src/platform/src/linux/mod.rs @@ -114,6 +114,14 @@ pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int { e(unsafe { syscall!(OPENAT, AT_FDCWD, path, oflag, mode) }) as c_int } +pub fn pipe(fildes: [c_int; 2]) -> c_int { + e(unsafe { syscall!(PIPE2, fildes.as_ptr(), 0) }) as c_int +} + +pub fn read(fildes: c_int, buf: &[u8]) -> ssize_t { + e(unsafe { syscall!(READ, fildes, buf.as_ptr(), buf.len()) }) as ssize_t +} + pub fn write(fildes: c_int, buf: &[u8]) -> ssize_t { e(unsafe { syscall!(WRITE, fildes, buf.as_ptr(), buf.len()) }) as ssize_t } diff --git a/src/platform/src/redox/mod.rs b/src/platform/src/redox/mod.rs index 057ad80ba0..95f149bddd 100644 --- a/src/platform/src/redox/mod.rs +++ b/src/platform/src/redox/mod.rs @@ -1,5 +1,8 @@ +extern crate alloc; + use core::ptr; use core::slice; +use alloc::Vec; use syscall; use c_str; @@ -119,6 +122,18 @@ pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int { e(syscall::open(path, (oflag as usize) | (mode as usize))) as c_int } +pub fn pipe(fds: [c_int; 2]) -> c_int { + let usize_vec = fds.iter().map(|x| *x as usize).collect::>(); + let usize_slice = usize_vec.as_slice(); + let mut usize_arr: [usize; 2] = Default::default(); + usize_arr.copy_from_slice(usize_slice); + e(syscall::pipe2(&mut usize_arr, 0)) as c_int +} + +pub fn read(fd: c_int, buf: &mut [u8]) -> ssize_t { + e(syscall::read(fd as usize, buf)) as ssize_t +} + pub fn write(fd: c_int, buf: &[u8]) -> ssize_t { e(syscall::write(fd as usize, buf)) as ssize_t } diff --git a/src/unistd/src/lib.rs b/src/unistd/src/lib.rs index 90811a6c7d..c9dc8804fd 100644 --- a/src/unistd/src/lib.rs +++ b/src/unistd/src/lib.rs @@ -295,7 +295,7 @@ pub extern "C" fn pause() -> c_int { #[no_mangle] pub extern "C" fn pipe(fildes: [c_int; 2]) -> c_int { - unimplemented!(); + platform::pipe(fildes) } #[no_mangle] @@ -324,7 +324,9 @@ pub extern "C" fn pwrite( #[no_mangle] pub extern "C" fn read(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t { - unimplemented!(); + use core::slice; + let buf = unsafe { slice::from_raw_parts_mut(buf as *mut u8, nbyte as usize) }; + platform::read(fildes, buf) } #[no_mangle] From 22fb6c5bf0a732db666c73f2cbabec2d2bcadcda Mon Sep 17 00:00:00 2001 From: Paul Sajna Date: Thu, 8 Mar 2018 11:20:13 -0800 Subject: [PATCH 4/9] copy strerror implementation into perror --- src/stdio/Cargo.toml | 1 + src/stdio/src/lib.rs | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/stdio/Cargo.toml b/src/stdio/Cargo.toml index dacf967fe2..570e409bd0 100644 --- a/src/stdio/Cargo.toml +++ b/src/stdio/Cargo.toml @@ -11,3 +11,4 @@ cbindgen = { path = "../../cbindgen" } platform = { path = "../platform" } va_list = { path = "../../va_list", features = ["no_std"] } string = { path = "../string" } +errno = { path = "../errno"} diff --git a/src/stdio/src/lib.rs b/src/stdio/src/lib.rs index 66128a1cd1..1f16600021 100644 --- a/src/stdio/src/lib.rs +++ b/src/stdio/src/lib.rs @@ -5,12 +5,15 @@ extern crate platform; extern crate va_list as vl; extern crate string; +extern crate errno; use core::str; use core::fmt::Write; use platform::types::*; use platform::c_str; +use platform::errno; +use errno::STR_ERROR; use vl::VaList as va_list; mod printf; @@ -207,12 +210,21 @@ pub extern "C" fn pclose(stream: *mut FILE) -> c_int { #[no_mangle] pub unsafe extern "C" fn perror(s: *const c_char) { - let strerror = string::strerror(platform::errno); + let mut buf: [u8; 256] = [0; 256]; + + let mut sw = platform::StringWriter(buf.as_mut_ptr(), buf.len()); + + if errno >= 0 && errno < STR_ERROR.len() as c_int { + sw.write_str(STR_ERROR[errno as usize]); + } else { + sw.write_fmt(format_args!("Unknown error {}", errno)); + } + let mut w = platform::FileWriter(2); w.write_fmt(format_args!( "{}: {}\n", str::from_utf8_unchecked(c_str(s)), - str::from_utf8_unchecked(c_str(strerror)) + str::from_utf8_unchecked(c_str(buf.as_mut_ptr() as *mut c_char)) )); } From 12833a5a5ca0fe4904fce81234f1b19236ee893d Mon Sep 17 00:00:00 2001 From: Paul Sajna Date: Thu, 8 Mar 2018 12:24:10 -0800 Subject: [PATCH 5/9] add test and fork --- src/platform/src/linux/mod.rs | 4 ++++ src/platform/src/redox/mod.rs | 4 ++++ src/unistd/src/lib.rs | 2 +- tests/.gitignore | 3 +++ tests/Makefile | 3 +++ tests/pipe.c | 23 +++++++++++++++++++++++ 6 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tests/pipe.c diff --git a/src/platform/src/linux/mod.rs b/src/platform/src/linux/mod.rs index 3f32ed2953..66fafabbb4 100644 --- a/src/platform/src/linux/mod.rs +++ b/src/platform/src/linux/mod.rs @@ -62,6 +62,10 @@ pub fn fchdir(fildes: c_int) -> c_int { e(unsafe { syscall!(FCHDIR, fildes) }) as c_int } +pub fn fork() -> pid_t { + e(unsafe {syscall!(FORK) }) as pid_t +} + pub fn fsync(fildes: c_int) -> c_int { e(unsafe { syscall!(FSYNC, fildes) }) as c_int } diff --git a/src/platform/src/redox/mod.rs b/src/platform/src/redox/mod.rs index 95f149bddd..e9fe6ddaff 100644 --- a/src/platform/src/redox/mod.rs +++ b/src/platform/src/redox/mod.rs @@ -66,6 +66,10 @@ pub fn fchdir(fd: c_int) -> c_int { } } +pub fn fork() -> pid_t { + e(unsafe { syscall::clone(0) }) as pid_t +} + pub fn fsync(fd: c_int) -> c_int { e(syscall::fsync(fd as usize)) as c_int } diff --git a/src/unistd/src/lib.rs b/src/unistd/src/lib.rs index c9dc8804fd..ea4609ba50 100644 --- a/src/unistd/src/lib.rs +++ b/src/unistd/src/lib.rs @@ -140,7 +140,7 @@ pub extern "C" fn fdatasync(fildes: c_int) -> c_int { #[no_mangle] pub extern "C" fn fork() -> pid_t { - unimplemented!(); + platform::fork() } #[no_mangle] diff --git a/tests/.gitignore b/tests/.gitignore index dead47ff35..e5819ec545 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,9 +1,11 @@ /alloc /args +/atoi /brk /chdir /create /create.out +/ctype /dup /dup.out /error @@ -15,5 +17,6 @@ /link /link.out /math +/pipe /printf /write diff --git a/tests/Makefile b/tests/Makefile index 7d293f7246..b371961d99 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,9 +1,11 @@ BINS=\ alloc \ + atoi \ brk \ args \ chdir \ create \ + ctype \ dup \ error \ fchdir \ @@ -12,6 +14,7 @@ BINS=\ getid \ link \ math \ + pipe \ printf \ write diff --git a/tests/pipe.c b/tests/pipe.c new file mode 100644 index 0000000000..0ad78bc3e5 --- /dev/null +++ b/tests/pipe.c @@ -0,0 +1,23 @@ +//http://www2.cs.uregina.ca/~hamilton/courses/330/notes/unix/pipes/pipes.html +#include + +int main() +{ + + int pid, pip[2]; + char instring[20]; + + pipe(pip); + + pid = fork(); + if (pid == 0) /* child : sends message to parent*/ + { + /* send 7 characters in the string, including end-of-string */ + write(pip[1], "Hi Mom!", 7); + } + else /* parent : receives message from child */ + { + /* read from the pipe */ + read(pip[0], instring, 7); + } +} From 38ed9ccb2221b9d0d8bc21a110760f99fc5279bc Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 8 Mar 2018 14:31:55 -0700 Subject: [PATCH 6/9] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index d47a17e90a..5a1a51a1bc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ # relibc C Library in Rust for Redox and Linux (WIP) + + +relibc is a portable POSIX C standard library written in Rust. It is under heavy development, and currently supports Redox and Linux. From e1a8b288fbfd160857b5fc86948c5eb74cfc1628 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 8 Mar 2018 14:32:06 -0700 Subject: [PATCH 7/9] Update README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 5a1a51a1bc..e55d89f29d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,2 @@ # relibc -C Library in Rust for Redox and Linux (WIP) - - relibc is a portable POSIX C standard library written in Rust. It is under heavy development, and currently supports Redox and Linux. From 18961114e2944cf2b3884861f72458d70a598ef5 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 8 Mar 2018 14:51:22 -0700 Subject: [PATCH 8/9] Simplify perror --- Cargo.lock | 2 +- src/stdio/Cargo.toml | 1 - src/stdio/src/lib.rs | 21 ++++++--------------- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab929b2e2d..06030c19ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -445,8 +445,8 @@ name = "stdio" version = "0.1.0" dependencies = [ "cbindgen 0.5.0", + "errno 0.1.0", "platform 0.1.0", - "string 0.1.0", "va_list 0.1.0", ] diff --git a/src/stdio/Cargo.toml b/src/stdio/Cargo.toml index 570e409bd0..2f53e58dc7 100644 --- a/src/stdio/Cargo.toml +++ b/src/stdio/Cargo.toml @@ -10,5 +10,4 @@ cbindgen = { path = "../../cbindgen" } [dependencies] platform = { path = "../platform" } va_list = { path = "../../va_list", features = ["no_std"] } -string = { path = "../string" } errno = { path = "../errno"} diff --git a/src/stdio/src/lib.rs b/src/stdio/src/lib.rs index 1f16600021..83d4446314 100644 --- a/src/stdio/src/lib.rs +++ b/src/stdio/src/lib.rs @@ -4,7 +4,6 @@ extern crate platform; extern crate va_list as vl; -extern crate string; extern crate errno; use core::str; @@ -210,22 +209,14 @@ pub extern "C" fn pclose(stream: *mut FILE) -> c_int { #[no_mangle] pub unsafe extern "C" fn perror(s: *const c_char) { - let mut buf: [u8; 256] = [0; 256]; - - let mut sw = platform::StringWriter(buf.as_mut_ptr(), buf.len()); - - if errno >= 0 && errno < STR_ERROR.len() as c_int { - sw.write_str(STR_ERROR[errno as usize]); - } else { - sw.write_fmt(format_args!("Unknown error {}", errno)); - } + let s_str = str::from_utf8_unchecked(c_str(s)); let mut w = platform::FileWriter(2); - w.write_fmt(format_args!( - "{}: {}\n", - str::from_utf8_unchecked(c_str(s)), - str::from_utf8_unchecked(c_str(buf.as_mut_ptr() as *mut c_char)) - )); + if errno >= 0 && errno < STR_ERROR.len() as c_int { + w.write_fmt(format_args!("{}: {}\n", s_str, STR_ERROR[errno as usize])); + } else { + w.write_fmt(format_args!("{}: Unknown error {}\n", s_str, errno)); + } } #[no_mangle] From cfbe27490f30a127a55c4bb165fea53a86338b77 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 8 Mar 2018 15:00:17 -0700 Subject: [PATCH 9/9] Remove allocation, fix pipe example --- src/platform/Cargo.toml | 3 --- src/platform/src/lib.rs | 2 -- src/platform/src/redox/mod.rs | 13 +++++-------- tests/pipe.c | 14 ++++++++++++-- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/platform/Cargo.toml b/src/platform/Cargo.toml index a00eb79be6..e25b8251c0 100644 --- a/src/platform/Cargo.toml +++ b/src/platform/Cargo.toml @@ -8,6 +8,3 @@ sc = "0.2" [target.'cfg(target_os = "redox")'.dependencies] redox_syscall = "0.1" - -[dependencies] -alloc-no-stdlib = "1.2" diff --git a/src/platform/src/lib.rs b/src/platform/src/lib.rs index 6359118c71..5f57298db7 100644 --- a/src/platform/src/lib.rs +++ b/src/platform/src/lib.rs @@ -3,8 +3,6 @@ #![no_std] #![allow(non_camel_case_types)] //TODO #![feature(thread_local)] -#![feature(alloc)] -extern crate alloc; #[cfg(all(not(feature = "no_std"), target_os = "linux"))] #[macro_use] diff --git a/src/platform/src/redox/mod.rs b/src/platform/src/redox/mod.rs index e9fe6ddaff..5a18ed234b 100644 --- a/src/platform/src/redox/mod.rs +++ b/src/platform/src/redox/mod.rs @@ -1,8 +1,5 @@ -extern crate alloc; - use core::ptr; use core::slice; -use alloc::Vec; use syscall; use c_str; @@ -127,11 +124,11 @@ pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int { } pub fn pipe(fds: [c_int; 2]) -> c_int { - let usize_vec = fds.iter().map(|x| *x as usize).collect::>(); - let usize_slice = usize_vec.as_slice(); - let mut usize_arr: [usize; 2] = Default::default(); - usize_arr.copy_from_slice(usize_slice); - e(syscall::pipe2(&mut usize_arr, 0)) as c_int + let mut usize_fds: [usize; 2] = [0; 2]; + let res = e(syscall::pipe2(&mut usize_fds)); + fds[0] = usize_fds[0] as c_int; + fds[1] = usize_fds[1] as c_int; + res as c_int } pub fn read(fd: c_int, buf: &mut [u8]) -> ssize_t { diff --git a/tests/pipe.c b/tests/pipe.c index 0ad78bc3e5..6772cd5112 100644 --- a/tests/pipe.c +++ b/tests/pipe.c @@ -1,4 +1,5 @@ //http://www2.cs.uregina.ca/~hamilton/courses/330/notes/unix/pipes/pipes.html +#include #include int main() @@ -6,18 +7,27 @@ int main() int pid, pip[2]; char instring[20]; + char * outstring = "Hello World!"; - pipe(pip); + pipe(pip); pid = fork(); if (pid == 0) /* child : sends message to parent*/ { + /* close read end */ + close(pip[0]); /* send 7 characters in the string, including end-of-string */ - write(pip[1], "Hi Mom!", 7); + write(pip[1], outstring, strlen(outstring)); + /* close write end */ + close(pip[1]); } else /* parent : receives message from child */ { + /* close write end */ + close(pip[1]); /* read from the pipe */ read(pip[0], instring, 7); + /* close read end */ + close(pip[0]); } }