diff --git a/Cargo.lock b/Cargo.lock index 9bf6efb87daac03a40baea146a417a6a2571b336..0ae5091493020bf1859e01e6db229f4bb7d6f35b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -491,6 +491,7 @@ dependencies = [ "cbindgen 0.5.2", "errno 0.1.0", "platform 0.1.0", + "signal 0.1.0", ] [[package]] diff --git a/include/malloc.h b/include/malloc.h new file mode 100644 index 0000000000000000000000000000000000000000..d7c21badfbb844d90bcddb8c1941936999f573dc --- /dev/null +++ b/include/malloc.h @@ -0,0 +1,16 @@ +#ifndef _MALLOC_H +#define _MALLOC_H + +#include <stddef.h> + +// Generated from: +// `grep "malloc\|calloc\|realloc\|free\|valloc\|memalign" target/include/stdlib.h` + +void *calloc(size_t nelem, size_t elsize); +void free(void *ptr); +void *malloc(size_t size); +void *memalign(size_t alignment, size_t size); +void *realloc(void *ptr, size_t size); +void *valloc(size_t size); + +#endif diff --git a/src/dirent/src/lib.rs b/src/dirent/src/lib.rs index 90549e01342dc5f0cce27682fe5762660f07c2f5..62edcf9a399f0079434d991fd7410f9d8fbc6134 100644 --- a/src/dirent/src/lib.rs +++ b/src/dirent/src/lib.rs @@ -44,7 +44,7 @@ pub extern "C" fn opendir(path: *const c_char) -> *mut DIR { let fd = platform::open( path, fcntl::O_RDONLY | fcntl::O_DIRECTORY | fcntl::O_CLOEXEC, - 0o755, + 0, ); if fd < 0 { diff --git a/src/platform/src/linux/mod.rs b/src/platform/src/linux/mod.rs index e7018fbfcfa238b67d8da1e58d5686d374c200db..99b2d6e08de653a35ef0476357e017a3b9b8d454 100644 --- a/src/platform/src/linux/mod.rs +++ b/src/platform/src/linux/mod.rs @@ -443,6 +443,10 @@ pub fn times(out: *mut tms) -> clock_t { unsafe { syscall!(TIMES, out) as clock_t } } +pub fn umask(mask: mode_t) -> mode_t { + unsafe { syscall!(UMASK, mask) as mode_t } +} + pub fn uname(utsname: *mut utsname) -> c_int { e(unsafe { syscall!(UNAME, utsname, 0) }) as c_int } diff --git a/src/platform/src/redox/mod.rs b/src/platform/src/redox/mod.rs index 691bf3c746459b54484a32913cbb8c3c790990be..48585668f3e9d4b7ebc5a20f884ea256d10e4c12 100644 --- a/src/platform/src/redox/mod.rs +++ b/src/platform/src/redox/mod.rs @@ -415,7 +415,7 @@ pub fn getgid() -> gid_t { } pub fn getrusage(who: c_int, r_usage: *mut rusage) -> c_int { - let _ = write!( + let _ = writeln!( FileWriter(2), "unimplemented: getrusage({}, {:p})", who, @@ -475,7 +475,7 @@ unsafe fn inner_get_name( } pub fn getitimer(which: c_int, out: *mut itimerval) -> c_int { - let _ = write!( + let _ = writeln!( FileWriter(2), "unimplemented: getitimer({}, {:p})", which, @@ -523,7 +523,7 @@ pub fn getsockopt( option_value: *mut c_void, option_len: *mut socklen_t, ) -> c_int { - let _ = write!( + let _ = writeln!( FileWriter(2), "unimplemented: getsockopt({}, {}, {}, {:p}, {:p})", socket, @@ -838,7 +838,7 @@ pub unsafe fn sendto( } pub fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int { - let _ = write!( + let _ = writeln!( FileWriter(2), "unimplemented: setitimer({}, {:p}, {:p})", which, @@ -871,7 +871,7 @@ pub fn setsockopt( option_value: *const c_void, option_len: socklen_t, ) -> c_int { - let _ = write!( + let _ = writeln!( FileWriter(2), "unimplemented: setsockopt({}, {}, {}, {:p}, {})", socket, @@ -884,7 +884,7 @@ pub fn setsockopt( } pub fn shutdown(socket: c_int, how: c_int) -> c_int { - let _ = write!( + let _ = writeln!( FileWriter(2), "unimplemented: shutdown({}, {})", socket, @@ -896,14 +896,14 @@ pub fn shutdown(socket: c_int, how: c_int) -> c_int { pub unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int { if !oact.is_null() { // Assumes the last sigaction() call was made by relibc and not a different one - if let Some(callback) = SIG_HANDLER { - (*oact).sa_handler = callback; + if SIG_HANDLER.is_some() { + (*oact).sa_handler = SIG_HANDLER; } } let act = if act.is_null() { None } else { - SIG_HANDLER = Some((*act).sa_handler); + SIG_HANDLER = (*act).sa_handler; let m = (*act).sa_mask; Some(syscall::SigAction { sa_handler: sig_handler, @@ -926,7 +926,7 @@ pub unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) } pub fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int { - let _ = write!( + let _ = writeln!( FileWriter(2), "unimplemented: sigprocmask({}, {:p}, {:p})", how, @@ -981,7 +981,7 @@ pub unsafe fn socket(domain: c_int, mut kind: c_int, protocol: c_int) -> c_int { } pub fn socketpair(domain: c_int, kind: c_int, protocol: c_int, socket_vector: *mut c_int) -> c_int { - let _ = write!( + let _ = writeln!( FileWriter(2), "unimplemented: socketpair({}, {}, {}, {:p})", domain, @@ -1029,10 +1029,15 @@ pub fn tcsetattr(fd: c_int, _act: c_int, value: *const termios) -> c_int { } pub fn times(out: *mut tms) -> clock_t { - let _ = write!(FileWriter(2), "unimplemented: times({:p})", out); + let _ = writeln!(FileWriter(2), "unimplemented: times({:p})", out); !0 } +pub fn umask(mask: mode_t) -> mode_t { + let _ = writeln!(FileWriter(2), "unimplemented: umask({})", mask); + 0 +} + pub fn unlink(path: *const c_char) -> c_int { let path = unsafe { c_str(path) }; e(syscall::unlink(path)) as c_int diff --git a/src/platform/src/types.rs b/src/platform/src/types.rs index bb09f4e22790df6e589f5a2f957c5c6dd2006e4f..bff380a3b873c3873486d2ae17477e0a9cf6a722 100644 --- a/src/platform/src/types.rs +++ b/src/platform/src/types.rs @@ -165,9 +165,9 @@ pub struct sockaddr_in { #[repr(C)] pub struct sigaction { - pub sa_handler: extern "C" fn(c_int), + pub sa_handler: Option<extern "C" fn(c_int)>, pub sa_flags: c_ulong, - pub sa_restorer: unsafe extern "C" fn(), + pub sa_restorer: Option<unsafe extern "C" fn()>, pub sa_mask: sigset_t, } diff --git a/src/pwd/src/lib.rs b/src/pwd/src/lib.rs index 300325c62a99cc87ec6c2332f46e136114bbebc1..6d82a1f9dd3b420c7fe200851597b5cb00860ae0 100644 --- a/src/pwd/src/lib.rs +++ b/src/pwd/src/lib.rs @@ -53,7 +53,7 @@ where let file = match RawFile::open( "/etc/passwd\0".as_ptr() as *const c_char, fcntl::O_RDONLY, - 0o644, + 0, ) { Ok(file) => file, Err(_) => return OptionPasswd::Error, diff --git a/src/signal/src/lib.rs b/src/signal/src/lib.rs index 49cf7b884bff1eab8769068a694c3a621f4ba6c7..1a463beeffc068689603baa1698eaa93bfc9c191 100644 --- a/src/signal/src/lib.rs +++ b/src/signal/src/lib.rs @@ -29,9 +29,14 @@ pub const SIG_SETMASK: c_int = 2; #[repr(C)] #[derive(Clone)] pub struct sigaction { - pub sa_handler: extern "C" fn(c_int), + // I don't actually want these to be optional. They can have more than just + // one invalid value. But because of rust's non-null optimization, this + // causes Some(sigaction) with a null sa_handler to become None. Maybe + // these should be usizes and transmuted when needed... However, then I + // couldn't let cbindgen do its job. + pub sa_handler: Option<extern "C" fn(c_int)>, pub sa_flags: c_ulong, - pub sa_restorer: unsafe extern "C" fn(), + pub sa_restorer: Option<unsafe extern "C" fn()>, pub sa_mask: sigset_t, } @@ -86,9 +91,20 @@ pub extern "C" fn sigaddset(set: *mut sigset_t, mut signo: c_int) -> c_int { 0 } -// #[no_mangle] +#[no_mangle] pub extern "C" fn sigdelset(set: *mut sigset_t, signo: c_int) -> c_int { - unimplemented!(); + if signo <= 0 || signo as usize > NSIG { + unsafe { + platform::errno = errno::EINVAL; + } + return -1; + } + + let signo = signo as usize - 1; // 0-indexed usize, please! + unsafe { + *set &= !(1 << (signo & (8 * mem::size_of::<sigset_t>() - 1))); + } + 0 } #[no_mangle] @@ -133,11 +149,11 @@ extern "C" { } #[no_mangle] -pub extern "C" fn signal(sig: c_int, func: extern "C" fn(c_int)) -> extern "C" fn(c_int) { +pub extern "C" fn signal(sig: c_int, func: Option<extern "C" fn(c_int)>) -> Option<extern "C" fn(c_int)> { let sa = sigaction { sa_handler: func, sa_flags: SA_RESTART as c_ulong, - sa_restorer: __restore_rt, + sa_restorer: Some(__restore_rt), sa_mask: sigset_t::default(), }; let mut old_sa = unsafe { mem::uninitialized() }; @@ -182,3 +198,38 @@ pub extern "C" fn sigsuspend(sigmask: *const sigset_t) -> c_int { pub extern "C" fn sigwait(set: *const sigset_t, sig: *mut c_int) -> c_int { unimplemented!(); } + +pub const _signal_strings: [&'static str; 32] = [ + "Unknown signal\0", + "Hangup\0", + "Interrupt\0", + "Quit\0", + "Illegal instruction\0", + "Trace/breakpoint trap\0", + "Aborted\0", + "Bus error\0", + "Arithmetic exception\0", + "Killed\0", + "User defined signal 1\0", + "Segmentation fault\0", + "User defined signal 2\0", + "Broken pipe\0", + "Alarm clock\0", + "Terminated\0", + "Stack fault\0", + "Child process status\0", + "Continued\0", + "Stopped (signal)\0", + "Stopped\0", + "Stopped (tty input)\0", + "Stopped (tty output)\0", + "Urgent I/O condition\0", + "CPU time limit exceeded\0", + "File size limit exceeded\0", + "Virtual timer expired\0", + "Profiling timer expired\0", + "Window changed\0", + "I/O possible\0", + "Power failure\0", + "Bad system call\0" +]; diff --git a/src/signal/src/linux.rs b/src/signal/src/linux.rs index f2cb86074f31b41a94023c6ce9d375a37fdbc0d0..a874b2652791fd71a5e43d180ea0e9ac97b7d1d2 100644 --- a/src/signal/src/linux.rs +++ b/src/signal/src/linux.rs @@ -48,7 +48,7 @@ pub const SIGVTALRM: usize = 26; pub const SIGPROF: usize = 27; pub const SIGWINCH: usize = 28; pub const SIGIO: usize = 29; -pub const SIGPOLL: usize = 29; +pub const SIGPOLL: usize = SIGIO; pub const SIGPWR: usize = 30; pub const SIGSYS: usize = 31; pub const SIGUNUSED: usize = SIGSYS; diff --git a/src/string/Cargo.toml b/src/string/Cargo.toml index bed689a677fc520b9a97e3bb16742afbd8369b06..69a3f03d745c073286f4f85b055c7585c1c0ea99 100644 --- a/src/string/Cargo.toml +++ b/src/string/Cargo.toml @@ -8,5 +8,6 @@ build = "build.rs" cbindgen = { path = "../../cbindgen" } [dependencies] -platform = { path = "../platform" } errno = { path = "../errno" } +platform = { path = "../platform" } +signal = { path = "../signal" } diff --git a/src/string/src/lib.rs b/src/string/src/lib.rs index 90a319c5049c7b2253eb10f3c1e3e65cde9de3c5..ec074f3ed8c974248f84433da3db916c57976eeb 100644 --- a/src/string/src/lib.rs +++ b/src/string/src/lib.rs @@ -3,6 +3,7 @@ extern crate errno; extern crate platform; +extern crate signal; use core::cmp; use core::mem; @@ -308,6 +309,13 @@ pub unsafe extern "C" fn strrchr(s: *const c_char, c: c_int) -> *mut c_char { ptr::null_mut() } +#[no_mangle] +pub unsafe extern "C" fn strsignal(sig: c_int) -> *mut c_char { + // Mutating this is undefined behavior I believe. But I just can't create a + // &'static mut str. Alternative is allocating everything on the heap... + signal::_signal_strings[sig as usize].as_ptr() as *const c_char as *mut c_char +} + #[no_mangle] pub unsafe extern "C" fn strspn(s1: *const c_char, s2: *const c_char) -> size_t { let s1 = s1 as *const u8; diff --git a/src/sys_stat/src/lib.rs b/src/sys_stat/src/lib.rs index ee31788bbeb3aa595108e9f1000fe1042dd4fbdf..a5b63af151d59fb337f43ca9345cd4376bcfe010 100644 --- a/src/sys_stat/src/lib.rs +++ b/src/sys_stat/src/lib.rs @@ -105,9 +105,9 @@ pub extern "C" fn stat(file: *const c_char, buf: *mut platform::types::stat) -> platform::stat(file, buf) } -// #[no_mangle] +#[no_mangle] pub extern "C" fn umask(mask: mode_t) -> mode_t { - unimplemented!(); + platform::umask(mask) } /*