From a9fcb973f682cdc0495c79950955c39a8e724db9 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Sun, 29 Jul 2018 07:18:44 -0600 Subject: [PATCH] Implement utimes and utime Format --- Cargo.lock | 9 +++++ Cargo.toml | 1 + src/arpainet/src/lib.rs | 2 +- src/dirent/src/lib.rs | 26 +++++++++---- src/lib.rs | 1 + src/platform/src/linux/mod.rs | 12 +++++- src/platform/src/rawfile.rs | 6 +-- src/platform/src/redox/mod.rs | 48 ++++++++++++++--------- src/platform/src/types.rs | 18 ++++----- src/pwd/src/lib.rs | 72 +++++++++++++++++++++++------------ src/signal/src/lib.rs | 10 +++-- src/signal/src/linux.rs | 12 ++++-- src/signal/src/redox.rs | 12 ++++-- src/sys_ioctl/src/lib.rs | 6 +-- src/sys_resource/src/lib.rs | 2 +- src/sys_socket/src/lib.rs | 30 ++++++++++++--- src/sys_stat/src/lib.rs | 4 +- src/sys_time/src/lib.rs | 23 ++++++++--- src/sys_times/src/lib.rs | 2 +- src/sys_un/src/lib.rs | 2 +- src/time/src/lib.rs | 5 ++- src/unistd/src/lib.rs | 8 ++-- src/utime/Cargo.toml | 11 ++++++ src/utime/build.rs | 11 ++++++ src/utime/cbindgen.toml | 7 ++++ src/utime/src/lib.rs | 29 ++++++++++++++ 26 files changed, 268 insertions(+), 101 deletions(-) create mode 100644 src/utime/Cargo.toml create mode 100644 src/utime/build.rs create mode 100644 src/utime/cbindgen.toml create mode 100644 src/utime/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 721878128..18d19d482 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -355,6 +355,7 @@ dependencies = [ "sys_wait 0.1.0", "time 0.1.0", "unistd 0.1.0", + "utime 0.1.0", "wchar 0.1.0", "wctype 0.1.0", ] @@ -690,6 +691,14 @@ dependencies = [ "sys_time 0.1.0", ] +[[package]] +name = "utime" +version = "0.1.0" +dependencies = [ + "cbindgen 0.5.2", + "platform 0.1.0", +] + [[package]] name = "va_list" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 77643812b..999b40b17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,7 @@ sys_utsname = { path = "src/sys_utsname" } sys_wait = { path = "src/sys_wait" } time = { path = "src/time" } unistd = { path = "src/unistd" } +utime = { path = "src/utime" } wchar = { path = "src/wchar" } wctype = { path = "src/wctype" } diff --git a/src/arpainet/src/lib.rs b/src/arpainet/src/lib.rs index 3ef6a8cf9..632cb3966 100644 --- a/src/arpainet/src/lib.rs +++ b/src/arpainet/src/lib.rs @@ -15,8 +15,8 @@ use core::str::FromStr; use core::{mem, ptr, slice, str}; use errno::*; use netinet::in_h::in_addr; -use platform::types::*; use platform::c_str; +use platform::types::*; #[no_mangle] pub extern "C" fn htonl(hostlong: u32) -> u32 { diff --git a/src/dirent/src/lib.rs b/src/dirent/src/lib.rs index 819b4d4b0..380b400e0 100644 --- a/src/dirent/src/lib.rs +++ b/src/dirent/src/lib.rs @@ -31,7 +31,7 @@ pub struct DIR { // Offset is like the total index, never erased It is used as an // alternative to dirent's d_off, but works on redox too. - offset: usize + offset: usize, } #[repr(C)] @@ -40,12 +40,16 @@ pub struct dirent { pub d_off: off_t, pub d_reclen: c_ushort, pub d_type: c_uchar, - pub d_name: [c_char; 256] + pub d_name: [c_char; 256], } #[no_mangle] 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); + let fd = platform::open( + path, + fcntl::O_RDONLY | fcntl::O_DIRECTORY | fcntl::O_CLOEXEC, + 0o755, + ); if fd < 0 { return ptr::null_mut(); @@ -56,7 +60,7 @@ pub extern "C" fn opendir(path: *const c_char) -> *mut DIR { buf: [0; _DIR_BUF_SIZE], index: 0, len: 0, - offset: 0 + offset: 0, })) } @@ -73,7 +77,7 @@ pub unsafe extern "C" fn readdir(dir: *mut DIR) -> *mut dirent { let read = platform::getdents( (*dir).fd, (*dir).buf.as_mut_ptr() as *mut platform::types::dirent, - (*dir).buf.len() + (*dir).buf.len(), ); if read <= 0 { if read != 0 && read != -errno::ENOENT { @@ -88,7 +92,8 @@ pub unsafe extern "C" fn readdir(dir: *mut DIR) -> *mut dirent { let ptr = (*dir).buf.as_mut_ptr().offset((*dir).index as isize) as *mut dirent; - #[cfg(target_os = "redox")] { + #[cfg(target_os = "redox")] + { if (*dir).index != 0 || (*dir).offset != 0 { // This should happen every time but the first, making the offset // point to the current element and not the next @@ -96,7 +101,8 @@ pub unsafe extern "C" fn readdir(dir: *mut DIR) -> *mut dirent { } (*ptr).d_off = (*dir).offset as off_t; } - #[cfg(not(target_os = "redox"))] { + #[cfg(not(target_os = "redox"))] + { (*dir).offset = (*ptr).d_off as usize; } @@ -104,7 +110,11 @@ pub unsafe extern "C" fn readdir(dir: *mut DIR) -> *mut dirent { ptr } // #[no_mangle] -pub extern "C" fn readdir_r(_dir: *mut DIR, _entry: *mut dirent, _result: *mut *mut dirent) -> *mut dirent { +pub extern "C" fn readdir_r( + _dir: *mut DIR, + _entry: *mut dirent, + _result: *mut *mut dirent, +) -> *mut dirent { unimplemented!(); // plus, deprecated } diff --git a/src/lib.rs b/src/lib.rs index 65e556ac6..8f1b88757 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,6 +37,7 @@ pub extern crate sys_utsname; pub extern crate sys_wait; pub extern crate time; pub extern crate unistd; +pub extern crate utime; pub extern crate wchar; pub extern crate wctype; diff --git a/src/platform/src/linux/mod.rs b/src/platform/src/linux/mod.rs index 8003b7f27..873720ed2 100644 --- a/src/platform/src/linux/mod.rs +++ b/src/platform/src/linux/mod.rs @@ -109,6 +109,10 @@ pub fn futimens(fd: c_int, times: *const timespec) -> c_int { e(unsafe { syscall!(UTIMENSAT, fd, ptr::null::<c_char>(), times, 0) }) as c_int } +pub fn utimens(path: *const c_char, times: *const timespec) -> c_int { + e(unsafe { syscall!(UTIMENSAT, AT_FDCWD, path, times, 0) }) as c_int +} + pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char { if e(unsafe { syscall!(GETCWD, buf, size) }) == !0 { ptr::null_mut() @@ -373,7 +377,13 @@ 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 { - e(syscall!(RT_SIGACTION, sig, act, oact, mem::size_of::<sigset_t>())) as c_int + e(syscall!( + RT_SIGACTION, + sig, + act, + oact, + mem::size_of::<sigset_t>() + )) as c_int } pub fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int { diff --git a/src/platform/src/rawfile.rs b/src/platform/src/rawfile.rs index 76aff649c..2efc20d48 100644 --- a/src/platform/src/rawfile.rs +++ b/src/platform/src/rawfile.rs @@ -1,5 +1,5 @@ +use super::{close, dup, open, types::*}; use core::ops::Deref; -use super::{open, dup, close, types::*}; pub struct RawFile(c_int); @@ -7,14 +7,14 @@ impl RawFile { pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> Result<RawFile, ()> { match open(path, oflag, mode) { -1 => Err(()), - n => Ok(RawFile(n)) + n => Ok(RawFile(n)), } } pub fn dup(&self) -> Result<RawFile, ()> { match dup(self.0) { -1 => Err(()), - n => Ok(RawFile(n)) + n => Ok(RawFile(n)), } } diff --git a/src/platform/src/redox/mod.rs b/src/platform/src/redox/mod.rs index 099f2fd1c..54a4f1bfc 100644 --- a/src/platform/src/redox/mod.rs +++ b/src/platform/src/redox/mod.rs @@ -248,15 +248,15 @@ pub fn fstat(fildes: c_int, buf: *mut stat) -> c_int { (*buf).st_blksize = redox_buf.st_blksize as blksize_t; (*buf).st_atim = timespec { tv_sec: redox_buf.st_atime as time_t, - tv_nsec: 0 + tv_nsec: 0, }; (*buf).st_mtim = timespec { tv_sec: redox_buf.st_mtime as time_t, - tv_nsec: 0 + tv_nsec: 0, }; (*buf).st_ctim = timespec { tv_sec: redox_buf.st_ctime as time_t, - tv_nsec: 0 + tv_nsec: 0, }; } } @@ -275,13 +275,24 @@ pub fn ftruncate(fd: c_int, len: off_t) -> c_int { } pub fn futimens(fd: c_int, times: *const timespec) -> c_int { - let times = [ - unsafe { redox_timespec::from(&*times) }, - unsafe { redox_timespec::from(&*times.offset(1)) } - ]; + let times = [unsafe { redox_timespec::from(&*times) }, unsafe { + redox_timespec::from(&*times.offset(1)) + }]; e(syscall::futimens(fd as usize, ×)) as c_int } +pub fn utimens(path: *const c_char, times: *const timespec) -> c_int { + let path = unsafe { c_str(path) }; + match syscall::open(path, O_STAT) { + Err(err) => e(Err(err)) as c_int, + Ok(fd) => { + let res = futimens(fd, times); + let _ = syscall::close(fd); + res + } + } +} + pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char { let buf_slice = unsafe { slice::from_raw_parts_mut(buf as *mut u8, size as usize) }; if e(syscall::getcwd(buf_slice)) == !0 { @@ -307,7 +318,7 @@ pub fn getdents(fd: c_int, mut dirents: *mut dirent, mut bytes: usize) -> c_int blen = match syscall::read(fd as usize, &mut buf) { Ok(0) => return amount, Ok(n) => n, - Err(err) => return -err.errno + Err(err) => return -err.errno, }; } @@ -320,7 +331,7 @@ pub fn getdents(fd: c_int, mut dirents: *mut dirent, mut bytes: usize) -> c_int d_off: 0, d_reclen: mem::size_of::<dirent>() as c_ushort, d_type: 0, - d_name: name + d_name: name, }; dirents = dirents.offset(1); } @@ -474,7 +485,10 @@ pub fn getsockopt( pub fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int { let mut redox_tp = redox_timespec::default(); - let err = e(syscall::clock_gettime(syscall::CLOCK_REALTIME, &mut redox_tp)) as c_int; + let err = e(syscall::clock_gettime( + syscall::CLOCK_REALTIME, + &mut redox_tp, + )) as c_int; if err < 0 { return err; } @@ -532,7 +546,7 @@ pub fn lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t { pub fn lstat(path: *const c_char, buf: *mut stat) -> c_int { let path = unsafe { c_str(path) }; - match syscall::open(path, O_RDONLY | O_NOFOLLOW) { + match syscall::open(path, O_STAT | O_NOFOLLOW) { Err(err) => e(Err(err)) as c_int, Ok(fd) => { let res = fstat(fd as i32, buf); @@ -737,14 +751,14 @@ pub unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) Some(syscall::SigAction { sa_handler: sig_handler, sa_mask: [0, m as u64], - sa_flags: (*act).sa_flags as usize + sa_flags: (*act).sa_flags as usize, }) }; let mut old = syscall::SigAction::default(); let ret = e(syscall::sigaction( sig as usize, act.as_ref(), - if oact.is_null() { None } else { Some(&mut old) } + if oact.is_null() { None } else { Some(&mut old) }, )) as c_int; if !oact.is_null() { let m = old.sa_mask; @@ -767,7 +781,7 @@ pub fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_i pub fn stat(path: *const c_char, buf: *mut stat) -> c_int { let path = unsafe { c_str(path) }; - match syscall::open(path, O_RDONLY) { + match syscall::open(path, O_STAT) { Err(err) => e(Err(err)) as c_int, Ok(fd) => { let res = fstat(fd as i32, buf); @@ -822,11 +836,7 @@ pub fn socketpair(domain: c_int, kind: c_int, protocol: c_int, socket_vector: *m } pub fn times(out: *mut tms) -> clock_t { - let _ = write!( - ::FileWriter(2), - "unimplemented: times({:p})", - out - ); + let _ = write!(::FileWriter(2), "unimplemented: times({:p})", out); !0 } diff --git a/src/platform/src/types.rs b/src/platform/src/types.rs index eaa7d18cd..4e83ffb90 100644 --- a/src/platform/src/types.rs +++ b/src/platform/src/types.rs @@ -1,5 +1,3 @@ -use core::mem; - #[cfg(target_os = "redox")] use syscall::data::TimeSpec as redox_timespec; // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable @@ -127,7 +125,7 @@ pub struct stat { // Compared to glibc, our struct is for some reason 24 bytes too small. // Accessing atime works, so clearly the struct isn't incorrect... // This works. - pub _pad: [c_char; 24] + pub _pad: [c_char; 24], } pub const AF_INET: c_int = 2; @@ -154,14 +152,14 @@ pub struct sockaddr { #[repr(C)] #[derive(Debug, Clone, Copy)] pub struct in_addr { - pub s_addr: in_addr_t + pub s_addr: in_addr_t, } #[repr(C)] pub struct sockaddr_in { pub sin_family: sa_family_t, pub sin_port: in_port_t, - pub sin_addr: in_addr + pub sin_addr: in_addr, } #[repr(C)] @@ -169,7 +167,7 @@ pub struct sigaction { pub sa_handler: extern "C" fn(c_int), pub sa_flags: c_ulong, pub sa_restorer: unsafe extern "C" fn(), - pub sa_mask: sigset_t + pub sa_mask: sigset_t, } pub type sigset_t = c_ulong; @@ -192,7 +190,7 @@ pub struct dirent { pub d_off: off_t, pub d_reclen: c_ushort, pub d_type: c_uchar, - pub d_name: [c_char; 256] + pub d_name: [c_char; 256], } #[repr(C)] @@ -201,7 +199,7 @@ pub struct winsize { ws_row: c_ushort, ws_col: c_ushort, ws_xpixel: c_ushort, - ws_ypixel: c_ushort + ws_ypixel: c_ushort, } #[repr(C)] @@ -221,7 +219,7 @@ pub struct rusage { pub ru_msgrcv: c_long, pub ru_nsignals: c_long, pub ru_nvcsw: c_long, - pub ru_nivcsw: c_long + pub ru_nivcsw: c_long, } #[repr(C)] @@ -229,5 +227,5 @@ pub struct tms { tms_utime: clock_t, tms_stime: clock_t, tms_cutime: clock_t, - tms_cstime: clock_t + tms_cstime: clock_t, } diff --git a/src/pwd/src/lib.rs b/src/pwd/src/lib.rs index 58acf3587..300325c62 100644 --- a/src/pwd/src/lib.rs +++ b/src/pwd/src/lib.rs @@ -10,8 +10,8 @@ extern crate platform; use alloc::vec::Vec; use core::ptr; -use platform::RawFile; use platform::types::*; +use platform::RawFile; #[repr(C)] pub struct passwd { @@ -21,7 +21,7 @@ pub struct passwd { pw_gid: gid_t, pw_gecos: *mut c_char, pw_dir: *mut c_char, - pw_shell: *mut c_char + pw_shell: *mut c_char, } static mut PASSWD_BUF: *mut c_char = ptr::null_mut(); @@ -32,23 +32,31 @@ static mut PASSWD: passwd = passwd { pw_gid: 0, pw_gecos: ptr::null_mut(), pw_dir: ptr::null_mut(), - pw_shell: ptr::null_mut() + pw_shell: ptr::null_mut(), }; enum OptionPasswd { Error, NotFound, - Found(*mut c_char) + Found(*mut c_char), } -fn pwd_lookup<F>(out: *mut passwd, alloc: Option<(*mut c_char, size_t)>, mut callback: F) -> OptionPasswd - where - // TODO F: FnMut(impl Iterator<Item = &[u8]>) -> bool - F: FnMut(&[&[u8]]) -> bool +fn pwd_lookup<F>( + out: *mut passwd, + alloc: Option<(*mut c_char, size_t)>, + mut callback: F, +) -> OptionPasswd +where + // TODO F: FnMut(impl Iterator<Item = &[u8]>) -> bool + F: FnMut(&[&[u8]]) -> bool, { - let file = match RawFile::open("/etc/passwd\0".as_ptr() as *const c_char, fcntl::O_RDONLY, 0o644) { + let file = match RawFile::open( + "/etc/passwd\0".as_ptr() as *const c_char, + fcntl::O_RDONLY, + 0o644, + ) { Ok(file) => file, - Err(_) => return OptionPasswd::Error + Err(_) => return OptionPasswd::Error, }; let mut buf = Vec::new(); @@ -110,7 +118,8 @@ fn pwd_lookup<F>(out: *mut passwd, alloc: Option<(*mut c_char, size_t)>, mut cal continue; } - let len = parts.iter() + let len = parts + .iter() .enumerate() .filter(|(i, _)| *i != 2 && *i != 3) .map(|(_, part)| part.len() + 1) @@ -125,7 +134,7 @@ fn pwd_lookup<F>(out: *mut passwd, alloc: Option<(*mut c_char, size_t)>, mut cal let alloc = match alloc { Some((alloc, _)) => alloc, - None => unsafe { platform::alloc(len) as *mut c_char } + None => unsafe { platform::alloc(len) as *mut c_char }, }; // _ prefix so it won't complain about the trailing // _off += <thing> @@ -153,14 +162,15 @@ fn pwd_lookup<F>(out: *mut passwd, alloc: Option<(*mut c_char, size_t)>, mut cal } _off += src.len() as isize + 1; }; - ($entry:expr, parse) => { + ($entry:expr,parse) => { unsafe { - $entry = parts.next() + $entry = parts + .next() .and_then(|part| core::str::from_utf8(part).ok()) .and_then(|part| part.parse().ok()) .unwrap_or(0); } - } + }; } copy_into!((*out).pw_name); @@ -176,8 +186,13 @@ fn pwd_lookup<F>(out: *mut passwd, alloc: Option<(*mut c_char, size_t)>, mut cal } #[no_mangle] -pub extern "C" fn getpwnam_r(name: *const c_char, out: *mut passwd, buf: *mut c_char, - size: size_t, result: *mut *mut passwd) -> c_int { +pub extern "C" fn getpwnam_r( + name: *const c_char, + out: *mut passwd, + buf: *mut c_char, + size: size_t, + result: *mut *mut passwd, +) -> c_int { match pwd_lookup(out, Some((buf, size)), |parts| { let part = parts.get(0).unwrap_or(&(&[] as &[u8])); for (i, c) in part.iter().enumerate() { @@ -201,15 +216,21 @@ pub extern "C" fn getpwnam_r(name: *const c_char, out: *mut passwd, buf: *mut c_ OptionPasswd::Found(_) => unsafe { *result = out; 0 - } + }, } } #[no_mangle] -pub extern "C" fn getpwuid_r(uid: uid_t, out: *mut passwd, buf: *mut c_char, - size: size_t, result: *mut *mut passwd) -> c_int { +pub extern "C" fn getpwuid_r( + uid: uid_t, + out: *mut passwd, + buf: *mut c_char, + size: size_t, + result: *mut *mut passwd, +) -> c_int { match pwd_lookup(out, Some((buf, size)), |parts| { - let part = parts.get(2) + let part = parts + .get(2) .and_then(|part| core::str::from_utf8(part).ok()) .and_then(|part| part.parse().ok()); part == Some(uid) @@ -225,7 +246,7 @@ pub extern "C" fn getpwuid_r(uid: uid_t, out: *mut passwd, buf: *mut c_char, OptionPasswd::Found(_) => unsafe { *result = out; 0 - } + }, } } @@ -248,14 +269,15 @@ pub extern "C" fn getpwnam(name: *const c_char) -> *mut passwd { OptionPasswd::Found(buf) => unsafe { PASSWD_BUF = buf; &mut PASSWD - } + }, } } #[no_mangle] pub extern "C" fn getpwuid(uid: uid_t) -> *mut passwd { match pwd_lookup(unsafe { &mut PASSWD }, None, |parts| { - let part = parts.get(2) + let part = parts + .get(2) .and_then(|part| core::str::from_utf8(part).ok()) .and_then(|part| part.parse().ok()); part == Some(uid) @@ -268,6 +290,6 @@ pub extern "C" fn getpwuid(uid: uid_t) -> *mut passwd { } PASSWD_BUF = buf; &mut PASSWD - } + }, } } diff --git a/src/signal/src/lib.rs b/src/signal/src/lib.rs index 099ce1149..49cf7b884 100644 --- a/src/signal/src/lib.rs +++ b/src/signal/src/lib.rs @@ -32,7 +32,7 @@ pub struct sigaction { pub sa_handler: extern "C" fn(c_int), pub sa_flags: c_ulong, pub sa_restorer: unsafe extern "C" fn(), - pub sa_mask: sigset_t + pub sa_mask: sigset_t, } pub const NSIG: usize = 64; @@ -54,7 +54,11 @@ pub extern "C" fn raise(sig: c_int) -> c_int { } #[no_mangle] -pub unsafe extern "C" fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int { +pub unsafe extern "C" fn sigaction( + sig: c_int, + act: *const sigaction, + oact: *mut sigaction, +) -> c_int { let mut _sigaction = None; let ptr = if !act.is_null() { _sigaction = Some((*act).clone()); @@ -134,7 +138,7 @@ pub extern "C" fn signal(sig: c_int, func: extern "C" fn(c_int)) -> extern "C" f sa_handler: func, sa_flags: SA_RESTART as c_ulong, sa_restorer: __restore_rt, - sa_mask: sigset_t::default() + sa_mask: sigset_t::default(), }; let mut old_sa = unsafe { mem::uninitialized() }; if unsafe { sigaction(sig, &sa, &mut old_sa) } < 0 { diff --git a/src/signal/src/linux.rs b/src/signal/src/linux.rs index 8f6b11f20..f2cb86074 100644 --- a/src/signal/src/linux.rs +++ b/src/signal/src/linux.rs @@ -1,18 +1,22 @@ // Needs to be defined in assembly because it can't have a function prologue #[cfg(target_arch = "x86_64")] -global_asm!(" +global_asm!( + " .global __restore_rt __restore_rt: mov $15, %rax # <- rax is register, 15 is RT_SIGRETURN syscall -"); +" +); #[cfg(target_arch = "aarch64")] -global_asm!(" +global_asm!( + " .global __restore_rt __restore_rt: mov x8, #139 # <- x8 is register, 139 is RT_SIGRETURN svc 0 -"); +" +); pub const SIGHUP: usize = 1; pub const SIGINT: usize = 2; diff --git a/src/signal/src/redox.rs b/src/signal/src/redox.rs index f5ae96b6c..e7c3f9d96 100644 --- a/src/signal/src/redox.rs +++ b/src/signal/src/redox.rs @@ -1,18 +1,22 @@ // Needs to be defined in assembly because it can't have a function prologue #[cfg(target_arch = "x86_64")] -global_asm!(" +global_asm!( + " .global __restore_rt __restore_rt: mov $119, %rax # <- rax is register, 119 is SIGRETURN int $0x80 -"); +" +); #[cfg(target_arch = "aarch64")] -global_asm!(" +global_asm!( + " .global __restore_rt __restore_rt: mov x8, #119 # <- x8 is register, 119 is SIGRETURN svc 0 -"); +" +); pub const SIGHUP: usize = 1; pub const SIGINT: usize = 2; diff --git a/src/sys_ioctl/src/lib.rs b/src/sys_ioctl/src/lib.rs index d62132a14..40b0427bf 100644 --- a/src/sys_ioctl/src/lib.rs +++ b/src/sys_ioctl/src/lib.rs @@ -13,19 +13,19 @@ pub struct sgttyb { sg_ospeed: c_char, sg_erase: c_char, sg_kill: c_char, - sg_flags: c_ushort + sg_flags: c_ushort, } #[cfg(target_os = "linux")] pub mod inner { - use ::*; + use *; #[repr(C)] pub struct winsize { ws_row: c_ushort, ws_col: c_ushort, ws_xpixel: c_ushort, - ws_ypixel: c_ushort + ws_ypixel: c_ushort, } #[no_mangle] diff --git a/src/sys_resource/src/lib.rs b/src/sys_resource/src/lib.rs index 3fde5a1fd..228f26fc7 100644 --- a/src/sys_resource/src/lib.rs +++ b/src/sys_resource/src/lib.rs @@ -40,7 +40,7 @@ pub struct rusage { pub ru_msgrcv: c_long, pub ru_nsignals: c_long, pub ru_nvcsw: c_long, - pub ru_nivcsw: c_long + pub ru_nivcsw: c_long, } // #[no_mangle] diff --git a/src/sys_socket/src/lib.rs b/src/sys_socket/src/lib.rs index 505bd5d50..7354e1b6e 100644 --- a/src/sys_socket/src/lib.rs +++ b/src/sys_socket/src/lib.rs @@ -28,7 +28,11 @@ pub unsafe extern "C" fn accept( address: *mut sockaddr, address_len: *mut socklen_t, ) -> c_int { - platform::accept(socket, address as *mut platform::types::sockaddr, address_len) + platform::accept( + socket, + address as *mut platform::types::sockaddr, + address_len, + ) } #[no_mangle] @@ -37,7 +41,11 @@ pub unsafe extern "C" fn bind( address: *const sockaddr, address_len: socklen_t, ) -> c_int { - platform::bind(socket, address as *const platform::types::sockaddr, address_len) + platform::bind( + socket, + address as *const platform::types::sockaddr, + address_len, + ) } #[no_mangle] @@ -46,7 +54,11 @@ pub unsafe extern "C" fn connect( address: *const sockaddr, address_len: socklen_t, ) -> c_int { - platform::connect(socket, address as *const platform::types::sockaddr, address_len) + platform::connect( + socket, + address as *const platform::types::sockaddr, + address_len, + ) } #[no_mangle] @@ -55,7 +67,11 @@ pub unsafe extern "C" fn getpeername( address: *mut sockaddr, address_len: *mut socklen_t, ) -> c_int { - platform::getpeername(socket, address as *mut platform::types::sockaddr, address_len) + platform::getpeername( + socket, + address as *mut platform::types::sockaddr, + address_len, + ) } #[no_mangle] @@ -64,7 +80,11 @@ pub unsafe extern "C" fn getsockname( address: *mut sockaddr, address_len: *mut socklen_t, ) -> c_int { - platform::getsockname(socket, address as *mut platform::types::sockaddr, address_len) + platform::getsockname( + socket, + address as *mut platform::types::sockaddr, + address_len, + ) } #[no_mangle] diff --git a/src/sys_stat/src/lib.rs b/src/sys_stat/src/lib.rs index e894e0c71..ee31788bb 100644 --- a/src/sys_stat/src/lib.rs +++ b/src/sys_stat/src/lib.rs @@ -6,7 +6,7 @@ extern crate platform; use platform::types::*; -pub const S_IFMT: c_int = 0o0170000; +pub const S_IFMT: c_int = 0o0170000; pub const S_IFBLK: c_int = 0o060000; pub const S_IFCHR: c_int = 0o020000; pub const S_IFIFO: c_int = 0o010000; @@ -52,7 +52,7 @@ pub struct stat { // Compared to glibc, our struct is for some reason 24 bytes too small. // Accessing atime works, so clearly the struct isn't incorrect... // This works. - pub _pad: [c_char; 24] + pub _pad: [c_char; 24], } #[no_mangle] diff --git a/src/sys_time/src/lib.rs b/src/sys_time/src/lib.rs index 6ebbf0163..fae8bfddc 100644 --- a/src/sys_time/src/lib.rs +++ b/src/sys_time/src/lib.rs @@ -48,13 +48,16 @@ pub extern "C" fn setitimer( platform::setitimer( which, value as *const platform::types::itimerval, - ovalue as *mut platform::types::itimerval + ovalue as *mut platform::types::itimerval, ) } #[no_mangle] pub extern "C" fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int { - platform::gettimeofday(tp as *mut platform::types::timeval, tzp as *mut platform::types::timezone) + platform::gettimeofday( + tp as *mut platform::types::timeval, + tzp as *mut platform::types::timezone, + ) } // #[no_mangle] @@ -68,9 +71,19 @@ pub extern "C" fn select( unimplemented!(); } -// #[no_mangle] -pub extern "C" fn utimes(path: *const c_char, times: [timeval; 2]) -> c_int { - unimplemented!(); +#[no_mangle] +pub unsafe extern "C" fn utimes(path: *const c_char, times: *const timeval) -> c_int { + let times_spec = [ + timespec { + tv_sec: (*times.offset(0)).tv_sec, + tv_nsec: ((*times.offset(0)).tv_usec as i64) * 1000, + }, + timespec { + tv_sec: (*times.offset(1)).tv_sec, + tv_nsec: ((*times.offset(1)).tv_usec as i64) * 1000, + }, + ]; + platform::utimens(path, times_spec.as_ptr()) } /* diff --git a/src/sys_times/src/lib.rs b/src/sys_times/src/lib.rs index 85cc11093..3d8b7f890 100644 --- a/src/sys_times/src/lib.rs +++ b/src/sys_times/src/lib.rs @@ -11,7 +11,7 @@ pub struct tms { tms_utime: clock_t, tms_stime: clock_t, tms_cutime: clock_t, - tms_cstime: clock_t + tms_cstime: clock_t, } #[no_mangle] diff --git a/src/sys_un/src/lib.rs b/src/sys_un/src/lib.rs index 577f49a04..19a75443a 100644 --- a/src/sys_un/src/lib.rs +++ b/src/sys_un/src/lib.rs @@ -9,5 +9,5 @@ use sys_socket::sa_family_t; #[repr(C)] pub struct sockaddr_un { sun_family: sa_family_t, - sun_path: [c_char; 108] + sun_path: [c_char; 108], } diff --git a/src/time/src/lib.rs b/src/time/src/lib.rs index 6ed95d831..3bfc2c8fe 100644 --- a/src/time/src/lib.rs +++ b/src/time/src/lib.rs @@ -329,7 +329,10 @@ pub unsafe extern "C" fn mktime(t: *const tm) -> time_t { #[no_mangle] pub extern "C" fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int { - platform::nanosleep(rqtp as *const platform::types::timespec, rmtp as *mut platform::types::timespec) + platform::nanosleep( + rqtp as *const platform::types::timespec, + rmtp as *mut platform::types::timespec, + ) } #[no_mangle] diff --git a/src/unistd/src/lib.rs b/src/unistd/src/lib.rs index f3deb9452..76dbb27b1 100644 --- a/src/unistd/src/lib.rs +++ b/src/unistd/src/lib.rs @@ -53,7 +53,7 @@ pub extern "C" fn alarm(seconds: c_uint) -> c_uint { let mut timer = sys_time::itimerval { it_value: sys_time::timeval { tv_sec: seconds as time_t, - tv_usec: 0 + tv_usec: 0, }, ..Default::default() }; @@ -455,12 +455,12 @@ pub extern "C" fn ualarm(value: useconds_t, interval: useconds_t) -> useconds_t let mut timer = sys_time::itimerval { it_value: sys_time::timeval { tv_sec: 0, - tv_usec: value as suseconds_t + tv_usec: value as suseconds_t, }, it_interval: sys_time::timeval { tv_sec: 0, - tv_usec: interval as suseconds_t - } + tv_usec: interval as suseconds_t, + }, }; let errno_backup = unsafe { platform::errno }; let usecs = if sys_time::setitimer(sys_time::ITIMER_REAL, &timer, &mut timer) < 0 { diff --git a/src/utime/Cargo.toml b/src/utime/Cargo.toml new file mode 100644 index 000000000..81bcd75cb --- /dev/null +++ b/src/utime/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "utime" +version = "0.1.0" +authors = ["Jeremy Soller <jackpot51@gmail.com>"] +build = "build.rs" + +[build-dependencies] +cbindgen = { path = "../../cbindgen" } + +[dependencies] +platform = { path = "../platform" } diff --git a/src/utime/build.rs b/src/utime/build.rs new file mode 100644 index 000000000..eb7b3b921 --- /dev/null +++ b/src/utime/build.rs @@ -0,0 +1,11 @@ +extern crate cbindgen; + +use std::{env, fs}; + +fn main() { + let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"); + fs::create_dir_all("../../target/include").expect("failed to create include directory"); + cbindgen::generate(crate_dir) + .expect("failed to generate bindings") + .write_to_file("../../target/include/utime.h"); +} diff --git a/src/utime/cbindgen.toml b/src/utime/cbindgen.toml new file mode 100644 index 000000000..37ed9f83d --- /dev/null +++ b/src/utime/cbindgen.toml @@ -0,0 +1,7 @@ +sys_includes = [] +include_guard = "_TEMPLATE_H" +language = "C" +style = "Tag" + +[enum] +prefix_with_name = true diff --git a/src/utime/src/lib.rs b/src/utime/src/lib.rs new file mode 100644 index 000000000..cea8b06f8 --- /dev/null +++ b/src/utime/src/lib.rs @@ -0,0 +1,29 @@ +//! utime implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/utime.h.html + +#![no_std] + +extern crate platform; + +use platform::types::*; + +#[repr(C)] +#[derive(Clone)] +pub struct utimbuf { + pub actime: time_t, + pub modtime: time_t, +} + +#[no_mangle] +pub unsafe extern "C" fn utime(filename: *const c_char, times: *const utimbuf) -> c_int { + let times_spec = [ + timespec { + tv_sec: (*times).actime, + tv_nsec: 0, + }, + timespec { + tv_sec: (*times).modtime, + tv_nsec: 0, + }, + ]; + platform::utimens(filename, times_spec.as_ptr()) +} -- GitLab