|
@@ -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
|