This commit is contained in:
Jeremy Soller
2018-04-26 20:12:57 -06:00
6 changed files with 183 additions and 20 deletions
+2
View File
@@ -35,6 +35,8 @@ typedef int clockid_t;
typedef void* timer_t;
typedef unsigned long int blkcnt_t;
#ifdef __linux__
#define _SC_PAGE_SIZE 30
#endif
+4
View File
@@ -54,6 +54,10 @@ pub unsafe fn c_str_n(s: *const c_char, n: usize) -> &'static [u8] {
slice::from_raw_parts(s as *const u8, size as usize)
}
pub unsafe fn cstr_from_bytes_with_nul_unchecked(bytes: &[u8]) -> *const c_char {
&*(bytes as *const [u8] as *const c_char)
}
pub struct FileWriter(pub c_int);
impl FileWriter {
+29 -2
View File
@@ -4,7 +4,9 @@ use errno;
use types::*;
const AT_FDCWD: c_int = -100;
const AT_EMPTY_PATH: c_int = 0x1000;
const AT_REMOVEDIR: c_int = 0x200;
const AT_SYMLINK_NOFOLLOW: c_int = 0x100;
pub fn e(sys: usize) -> usize {
if (sys as isize) < 0 && (sys as isize) >= -256 {
@@ -32,6 +34,10 @@ pub fn chdir(path: *const c_char) -> c_int {
e(unsafe { syscall!(CHDIR, path) }) as c_int
}
pub fn chmod(path: *const c_char, mode: mode_t) -> c_int {
e(unsafe { syscall!(FCHMODAT, AT_FDCWD, path, mode, 0) }) as c_int
}
pub fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int {
e(unsafe { syscall!(FCHOWNAT, AT_FDCWD, path, owner as u32, group as u32) }) as c_int
}
@@ -55,12 +61,21 @@ pub fn exit(status: c_int) -> ! {
loop {}
}
pub fn fchdir(fildes: c_int) -> c_int {
e(unsafe { syscall!(FCHDIR, fildes) }) as c_int
}
pub fn fchmod(fildes: c_int, mode: mode_t) -> c_int {
e(unsafe { syscall!(FCHMOD, fildes, mode) }) as c_int
}
pub fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int {
e(unsafe { syscall!(FCHOWN, fildes, owner, group) }) as c_int
}
pub fn fchdir(fildes: c_int) -> c_int {
e(unsafe { syscall!(FCHDIR, fildes) }) as c_int
pub fn fstat(fildes: c_int, buf: *mut stat) -> c_int {
let empty_cstr: *const c_char = unsafe { ::cstr_from_bytes_with_nul_unchecked(b"\0") };
e(unsafe { syscall!(NEWFSTATAT, fildes, empty_cstr, buf, AT_EMPTY_PATH) }) as c_int
}
pub fn fcntl(fildes: c_int, cmd: c_int, arg: c_int) -> c_int {
@@ -131,10 +146,18 @@ pub fn lseek(fildes: c_int, offset: off_t, whence: c_int) -> off_t {
e(unsafe { syscall!(LSEEK, fildes, offset, whence) }) as off_t
}
pub fn lstat(file: *const c_char, buf: *mut stat) -> c_int {
e(unsafe { syscall!(NEWFSTATAT, AT_FDCWD, file, buf, AT_SYMLINK_NOFOLLOW) }) as c_int
}
pub fn mkdir(path: *const c_char, mode: mode_t) -> c_int {
e(unsafe { syscall!(MKDIRAT, AT_FDCWD, path, mode) }) as c_int
}
pub fn mkfifo(path: *const c_char, mode: mode_t) -> c_int {
e(unsafe { syscall!(MKNODAT, AT_FDCWD, path, mode, 0) }) as c_int
}
pub fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int {
e(unsafe { syscall!(NANOSLEEP, rqtp, rmtp) }) as c_int
}
@@ -171,6 +194,10 @@ pub fn setreuid(ruid: uid_t, euid: uid_t) -> c_int {
e(unsafe { syscall!(SETREUID, ruid, euid) }) as c_int
}
pub fn stat(file: *const c_char, buf: *mut stat) -> c_int {
e(unsafe { syscall!(NEWFSTATAT, AT_FDCWD, file, buf, 0) }) as c_int
}
pub fn unlink(path: *const c_char) -> c_int {
e(unsafe { syscall!(UNLINKAT, AT_FDCWD, path, 0) }) as c_int
}
+94 -9
View File
@@ -1,9 +1,9 @@
use core::ptr;
use core::slice;
use core::mem;
use syscall;
use syscall::flag::*;
use syscall::data::TimeSpec as redox_timespec;
use syscall::data::Stat as redox_stat;
use c_str;
use errno;
@@ -30,10 +30,28 @@ pub fn chdir(path: *const c_char) -> c_int {
e(syscall::chdir(path)) as c_int
}
pub fn chmod(path: *const c_char, mode: mode_t) -> c_int {
let path = unsafe { c_str(path) };
match syscall::open(path, O_WRONLY) {
Err(err) => e(Err(err)) as c_int,
Ok(fd) => {
let res = syscall::fchmod(fd as usize, mode);
let _ = syscall::close(fd);
e(res) as c_int
}
}
}
pub fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int {
let path = unsafe { c_str(path) };
let fd = syscall::open(path, 0x0001).unwrap();
e(syscall::fchown(fd as usize, owner as u32, group as u32)) as c_int
match syscall::open(path, O_WRONLY) {
Err(err) => e(Err(err)) as c_int,
Ok(fd) => {
let res = syscall::fchown(fd as usize, owner as u32, group as u32);
let _ = syscall::close(fd);
e(res) as c_int
}
}
}
pub fn close(fd: c_int) -> c_int {
@@ -49,14 +67,10 @@ pub fn dup2(fd1: c_int, fd2: c_int) -> c_int {
}
pub fn exit(status: c_int) -> ! {
syscall::exit(status as usize);
let _ = syscall::exit(status as usize);
loop {}
}
pub fn fchown(fd: c_int, owner: uid_t, group: gid_t) -> c_int {
e(syscall::fchown(fd as usize, owner as u32, group as u32)) as c_int
}
pub fn fchdir(fd: c_int) -> c_int {
let path: &mut [u8] = &mut [0; 4096];
if e(syscall::fpath(fd as usize, path)) == !0 {
@@ -66,6 +80,14 @@ pub fn fchdir(fd: c_int) -> c_int {
}
}
pub fn fchmod(fd: c_int, mode: mode_t) -> c_int {
e(syscall::fchmod(fd as usize, mode)) as c_int
}
pub fn fchown(fd: c_int, owner: uid_t, group: gid_t) -> c_int {
e(syscall::fchown(fd as usize, owner as u32, group as u32)) as c_int
}
pub fn fcntl(fd: c_int, cmd: c_int, args: c_int) -> c_int {
e(syscall::fcntl(fd as usize, cmd as usize, args as usize)) as c_int
}
@@ -74,6 +96,33 @@ pub fn fork() -> pid_t {
e(unsafe { syscall::clone(0) }) as pid_t
}
pub fn fstat(fildes: c_int, buf: *mut stat) -> c_int {
let mut redox_buf: redox_stat = redox_stat::default();
match e(syscall::fstat(fildes as usize, &mut redox_buf)) {
0 => {
unsafe {
if !buf.is_null() {
(*buf).st_dev = redox_buf.st_dev as dev_t;
(*buf).st_ino = redox_buf.st_ino as ino_t;
(*buf).st_nlink = redox_buf.st_nlink as nlink_t;
(*buf).st_mode = redox_buf.st_mode;
(*buf).st_uid = redox_buf.st_uid as uid_t;
(*buf).st_gid = redox_buf.st_gid as gid_t;
// TODO st_rdev
(*buf).st_rdev = 0;
(*buf).st_size = redox_buf.st_size as off_t;
(*buf).st_blksize = redox_buf.st_blksize as blksize_t;
(*buf).st_atim = redox_buf.st_atime as time_t;
(*buf).st_mtim = redox_buf.st_mtime as time_t;
(*buf).st_ctim = redox_buf.st_ctime as time_t;
}
}
0
}
_ => -1,
}
}
pub fn fsync(fd: c_int) -> c_int {
e(syscall::fsync(fd as usize)) as c_int
}
@@ -141,12 +190,36 @@ pub fn lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t {
)) as 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) {
Err(err) => e(Err(err)) as c_int,
Ok(fd) => {
let res = fstat(fd as i32, buf);
let _ = syscall::close(fd);
res
}
}
}
pub fn mkdir(path: *const c_char, mode: mode_t) -> c_int {
let flags = O_CREAT | O_EXCL | O_CLOEXEC | O_DIRECTORY | mode as usize & 0o777;
let path = unsafe { c_str(path) };
match syscall::open(path, flags) {
Ok(fd) => {
syscall::close(fd);
let _ = syscall::close(fd);
0
}
Err(err) => e(Err(err)) as c_int,
}
}
pub fn mkfifo(path: *const c_char, mode: mode_t) -> c_int {
let flags = O_CREAT | MODE_FIFO as usize | mode as usize & 0o777;
let path = unsafe { c_str(path) };
match syscall::open(path, flags) {
Ok(fd) => {
let _ = syscall::close(fd);
0
}
Err(err) => e(Err(err)) as c_int,
@@ -221,6 +294,18 @@ pub fn setreuid(ruid: uid_t, euid: uid_t) -> c_int {
e(syscall::setreuid(ruid as usize, euid as usize)) as c_int
}
pub fn stat(path: *const c_char, buf: *mut stat) -> c_int {
let path = unsafe { c_str(path) };
match syscall::open(path, O_RDONLY) {
Err(err) => e(Err(err)) as c_int,
Ok(fd) => {
let res = fstat(fd as i32, buf);
let _ = syscall::close(fd);
res
}
}
}
pub fn unlink(path: *const c_char) -> c_int {
let path = unsafe { c_str(path) };
e(syscall::unlink(path)) as c_int
+18
View File
@@ -59,6 +59,7 @@ pub type dev_t = usize;
pub type ino_t = usize;
pub type nlink_t = usize;
pub type blksize_t = isize;
pub type blkcnt_t = u64;
pub type useconds_t = i32;
pub type suseconds_t = i64;
@@ -83,3 +84,20 @@ impl<'a> From<&'a timespec> for redox_timespec {
}
}
}
#[repr(C)]
pub struct stat {
pub st_dev: dev_t,
pub st_ino: ino_t,
pub st_nlink: nlink_t,
pub st_mode: mode_t,
pub st_uid: uid_t,
pub st_gid: gid_t,
pub st_rdev: dev_t,
pub st_size: off_t,
pub st_blksize: blksize_t,
pub st_atim: time_t,
pub st_mtim: time_t,
pub st_ctim: time_t,
pub st_blocks: blkcnt_t,
}
+36 -9
View File
@@ -6,6 +6,32 @@ extern crate platform;
use platform::types::*;
pub const S_IFMT: c_int = 00170000;
pub const S_IFBLK: c_int = 0060000;
pub const S_IFCHR: c_int = 0020000;
pub const S_IFIFO: c_int = 0010000;
pub const S_IFREG: c_int = 0100000;
pub const S_IFDIR: c_int = 0040000;
pub const S_IFLNK: c_int = 0120000;
pub const S_IRWXU: c_int = 00700;
pub const S_IRUSR: c_int = 00400;
pub const S_IWUSR: c_int = 00200;
pub const S_IXUSR: c_int = 00100;
pub const S_IRWXG: c_int = 00070;
pub const S_IRGRP: c_int = 00040;
pub const S_IWGRP: c_int = 00020;
pub const S_IXGRP: c_int = 00010;
pub const S_IRWXO: c_int = 00007;
pub const S_IROTH: c_int = 00004;
pub const S_IWOTH: c_int = 00002;
pub const S_IXOTH: c_int = 00001;
pub const S_ISUID: c_int = 04000;
pub const S_ISGID: c_int = 02000;
pub const S_ISVTX: c_int = 01000;
#[repr(C)]
pub struct stat {
pub st_dev: dev_t,
@@ -20,26 +46,27 @@ pub struct stat {
pub st_atim: time_t,
pub st_mtim: time_t,
pub st_ctim: time_t,
pub st_blocks: blkcnt_t,
}
#[no_mangle]
pub extern "C" fn chmod(path: *const c_char, mode: mode_t) -> c_int {
unimplemented!();
platform::chmod(path, mode)
}
#[no_mangle]
pub extern "C" fn fchmod(fildes: c_int, mode: mode_t) -> c_int {
unimplemented!();
platform::fchmod(fildes, mode)
}
#[no_mangle]
pub extern "C" fn fstat(fildes: c_int, buf: *mut stat) -> c_int {
unimplemented!();
pub extern "C" fn fstat(fildes: c_int, buf: *mut platform::types::stat) -> c_int {
platform::fstat(fildes, buf)
}
#[no_mangle]
pub extern "C" fn lstat(path: *const c_char, buf: *mut stat) -> c_int {
unimplemented!();
pub extern "C" fn lstat(path: *const c_char, buf: *mut platform::types::stat) -> c_int {
platform::lstat(path, buf)
}
#[no_mangle]
@@ -49,7 +76,7 @@ pub extern "C" fn mkdir(path: *const c_char, mode: mode_t) -> c_int {
#[no_mangle]
pub extern "C" fn mkfifo(path: *const c_char, mode: mode_t) -> c_int {
unimplemented!();
platform::mkfifo(path, mode)
}
#[no_mangle]
@@ -58,8 +85,8 @@ pub extern "C" fn mknod(path: *const c_char, mode: mode_t, dev: dev_t) -> c_int
}
#[no_mangle]
pub extern "C" fn stat(file: *const c_char, buf: *mut stat) -> c_int {
unimplemented!();
pub extern "C" fn stat(file: *const c_char, buf: *mut platform::types::stat) -> c_int {
platform::stat(file, buf)
}
#[no_mangle]