diff --git a/Cargo.lock b/Cargo.lock index 557319c6df231f95c8c888aeafe9a7ad72026976..ab929b2e2dd5716bc56821f027170140a0fb4b19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -446,6 +446,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 e64c0df1a573822c7169f99b5041c08070749bbb..570e409bd012b742ed12e710775ae776bf39da35 100644 --- a/src/stdio/Cargo.toml +++ b/src/stdio/Cargo.toml @@ -10,3 +10,5 @@ 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 7ac9d8170dc991fd7033a78d1bfb98199085e9fb..1f166000216c8899d1f4dfa3c7787b5d90fcc557 100644 --- a/src/stdio/src/lib.rs +++ b/src/stdio/src/lib.rs @@ -4,10 +4,16 @@ extern crate platform; extern crate va_list as vl; +extern crate string; +extern crate errno; -use core::slice; +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; @@ -203,8 +209,23 @@ 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 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(buf.as_mut_ptr() as *mut c_char)) + )); } #[no_mangle] diff --git a/tests/error.c b/tests/error.c index 67fb25ed394c43fb1771d8bf2ec897097ca5fe75..9ab04c2bd967a08d2d8089c8d94deb00c31266d3 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"); }