Browse Source

Add the last few things for bash to compile :D

jD91mZM2 6 years ago
parent
commit
ba8bd8c4e8

+ 1 - 0
Cargo.lock

@@ -491,6 +491,7 @@ dependencies = [
  "cbindgen 0.5.2",
  "errno 0.1.0",
  "platform 0.1.0",
+ "signal 0.1.0",
 ]
 
 [[package]]

+ 16 - 0
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

+ 1 - 1
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 {

+ 4 - 0
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
 }

+ 17 - 12
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

+ 2 - 2
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,
 }
 

+ 1 - 1
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,

+ 57 - 6
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"
+];

+ 1 - 1
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;

+ 2 - 1
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" }

+ 8 - 0
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;

+ 2 - 2
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)
 }
 
 /*