Implement utimes and utime
Format
This commit is contained in:
Generated
+9
@@ -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"
|
||||
|
||||
@@ -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" }
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+18
-8
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
+47
-25
@@ -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
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
+18
-5
@@ -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())
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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],
|
||||
}
|
||||
|
||||
+4
-1
@@ -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]
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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" }
|
||||
@@ -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");
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
sys_includes = []
|
||||
include_guard = "_TEMPLATE_H"
|
||||
language = "C"
|
||||
style = "Tag"
|
||||
|
||||
[enum]
|
||||
prefix_with_name = true
|
||||
@@ -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())
|
||||
}
|
||||
Reference in New Issue
Block a user