diff --git a/platform/src/linux/mod.rs b/platform/src/linux/mod.rs index adc1994cfe..e2a47dd776 100644 --- a/platform/src/linux/mod.rs +++ b/platform/src/linux/mod.rs @@ -2,12 +2,46 @@ use types::*; const AT_FDCWD: c_int = -100; +pub fn brk(addr: *const c_void) -> c_int { + unsafe { + let newbrk = syscall!(BRK, addr); + if newbrk < addr as usize { + return -1 + } + 0 + } +} + +pub fn chdir(path: *const c_char) -> c_int { + unsafe { + syscall!(CHDIR, path) as c_int + } +} + +pub fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int { + unsafe { + syscall!(CHOWN, owner as u32, group as u32) as c_int + } +} + pub fn close(fildes: c_int) -> c_int { unsafe { syscall!(CLOSE, fildes) as c_int } } +pub fn dup(fildes: c_int) -> c_int { + unsafe { + syscall!(DUP, fildes) as c_int + } +} + +pub fn dup2(fildes: c_int, fildes2:c_int) -> c_int { + unsafe { + syscall!(DUP2, fildes, fildes2) as c_int + } +} + pub fn exit(status: c_int) -> ! { unsafe { syscall!(EXIT, status); @@ -15,6 +49,85 @@ pub fn exit(status: c_int) -> ! { loop {} } +pub fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int { + unsafe { + syscall!(FCHOWN, owner, group) as c_int + } +} + +pub fn fchdir(fildes: c_int) -> c_int { + unsafe { + syscall!(FCHDIR, fildes) as c_int + } +} + +pub fn fsync(fildes: c_int) -> c_int { + unsafe { + syscall!(FSYNC, fildes) as c_int + } +} + +pub fn ftruncate(fildes: c_int, length: off_t) -> c_int { + unsafe { + syscall!(FTRUNCATE, fildes, length) as c_int + } +} + +pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char { + unsafe { + syscall!(GETCWD, buf, size); + buf as *mut c_char + } +} + +pub fn getegid() -> gid_t { + unsafe { + syscall!(GETEGID) + } +} + +pub fn geteuid() -> uid_t { + unsafe { + syscall!(GETEUID) + } +} + +pub fn getgid() -> gid_t { + unsafe { + syscall!(GETGID) + } +} + +pub fn getpgid(pid: pid_t) -> pid_t { + unsafe { + syscall!(GETPGID, pid) + } +} + +pub fn getpid() -> pid_t { + unsafe { + syscall!(GETPID) + } +} + +pub fn getppid() -> pid_t { + unsafe { + syscall!(GETPPID) + } +} + +pub fn getuid() -> uid_t { + unsafe { + syscall!(GETUID) + } +} + +pub fn link(path1: *const c_char, path2: *const c_char) -> c_int { + unsafe { + syscall!(LINK, path1, path2) as c_int + } +} + #[cfg(target_arch = "x86_64")] pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int { unsafe { diff --git a/platform/src/rawfile.rs b/platform/src/rawfile.rs new file mode 100644 index 0000000000..d4ee4bee60 --- /dev/null +++ b/platform/src/rawfile.rs @@ -0,0 +1,27 @@ +use core::ops::Deref; + +pub struct RawFile(usize); + +impl RawFile { + pub fn open>(path: T, flags: usize) -> Result { + open(path, flags).map(RawFile) + } + + pub fn dup(&self, buf: &[u8]) -> Result { + dup(self.0, buf).map(RawFile) + } +} + +impl Drop for RawFile { + fn drop(&mut self) { + let _ = close(self.0); + } +} + +impl Deref for RawFile { + type Target = usize; + + fn deref(&self) -> &usize { + &self.0 + } +} diff --git a/platform/src/redox/mod.rs b/platform/src/redox/mod.rs index b1178bf55e..ffe622eba1 100644 --- a/platform/src/redox/mod.rs +++ b/platform/src/redox/mod.rs @@ -1,18 +1,103 @@ +use core::slice; use syscall; - use c_str; use types::*; +pub fn brk(addr: *const c_void) -> { + syscall::brk(addr as usize).unwrap_or(-1) as c_int + + pub fn chdir(path: *const c_char) -> c_int { + let path = unsafe { c_str(path) }; + syscall::chdir(path).unwrap_or(-1) as c_int + } + + +pub fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int { + let fd = syscall::open(cstr_to_slice(path)); + syscall::fchown(fd as usize, owner as usize, group as usize).unwrap_or(-1) as c_int + pub fn close(fd: c_int) -> c_int { syscall::close(fd as usize); 0 } +pub fn dup(fd: c_int) -> c_int { + syscall::dup(fd as usize, &[]).unwrap_or(-1) as c_int +} + +pub fn dup2(fd1: c_int, fd2) -> c_int { + syscall::dup2(fd1 as usize, fd2 as usize, &[]).unwrap_or(-1) as c_int +} + pub fn exit(status: c_int) -> ! { syscall::exit(status as usize); loop {} } +pub fn fchown(fd: c_int, owner: uid_t, group: gid_t) -> c_int { + syscall::fchown(owner as usize, group as usize).unwrap_or(-1) as c_int +} + +pub fn fchdir(fd: c_int) -> c_int { + let result = fpath(fd as usize, &[]); + if result.is_ok() { + syscall::chdir(path).unwrap_or(-1) as c_int + } else { + -1 + } +} + +pub fn fsync(fd: c_int) -> c_int { + syscall::fsync(fd as usize).unwrap_or(-1) as c_int +} + +pub fn ftruncate(fd: c_int, len: off_t) -> { + syscall::ftruncate(fd as usize, len as usize).unwrap_or(-1) as c_int +} + +pub fn getcwd(buf: *mut c_char, size: size_t) -> { + // XXX: do something with size maybe + let rbuf = unsafe { c_str(buf) }; + syscall::getcwd(rbuf); + unsafe { + &*(rbuf as *mut [c_char]) + } +} + +pub fn getegid() -> gid_t { + syscall::getegid().unwrap_or(-1) as gid_t +} + +pub fn geteuid() -> uid_t { + syscall::geteuid().unwrap_or(-1) as uid_t +} + +pub fn getgid() -> gid_t { + syscall::getgid().unwrap_or(-1) as gid_t +} + +pub fn getpgid(pid: pid_t) -> pid_t { + syscall::getpgid(pid as usize).unwrap_or(-1) as pid_t +} + +pub fn getpid() -> pid_t { + syscall::getpid().unwrap_or(-1) as pid_t +} + +pub fn getppid() -> pid_t { + syscall::getppid().unwrap_or(-1) as pid_t +} + +pub fn getuid() -> uid_t { + syscall::getuid().unwrap_or(-1) as pid_t +} + +pub fn link(path1: const c_char, path2: const c_char) -> c_int { + let path1 = unsafe { c_str(path1) }; + let path2 = unsafe { c_str(path2) }; + syscall::link(path1, path2).unwrap_or(-1) as c_int +} + pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int { let path = unsafe { c_str(path) }; syscall::open(path, (oflag as usize) | (mode as usize)).unwrap() as c_int diff --git a/src/stdio/src/lib.rs b/src/stdio/src/lib.rs index eb20b34308..529097c2fc 100644 --- a/src/stdio/src/lib.rs +++ b/src/stdio/src/lib.rs @@ -190,13 +190,6 @@ pub extern "C" fn getchar_unlocked() -> c_int { unimplemented!(); } -#[no_mangle] -pub extern "C" fn getopt(argc: c_int, - argv: *const *const c_char, - optstring: c_char) -> c_int { - unimplemented!(); -} - #[no_mangle] pub extern "C" fn gets(s: *mut c_char) -> *mut c_char { diff --git a/src/unistd/src/lib.rs b/src/unistd/src/lib.rs index cf911b4f6c..b4ff1d9833 100644 --- a/src/unistd/src/lib.rs +++ b/src/unistd/src/lib.rs @@ -41,12 +41,12 @@ pub extern "C" fn alarm(seconds: c_uint) -> c_uint { #[no_mangle] pub extern "C" fn brk(addr: *mut c_void) -> c_int { - unimplemented!(); + platform::brk(addr) } #[no_mangle] pub extern "C" fn chdir(path: *const c_char) -> c_int { - unimplemented!(); + platform::chdir(path) } #[no_mangle] @@ -56,7 +56,7 @@ pub extern "C" fn chroot(path: *const c_char) -> c_int { #[no_mangle] pub extern "C" fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int { - unimplemented!(); + platform::chown(path, owner, group) } #[no_mangle] @@ -74,24 +74,14 @@ pub extern "C" fn crypt(key: *const c_char, salt: *const c_char) -> *mut c_char unimplemented!(); } -#[no_mangle] -pub extern "C" fn ctermid(s: *mut c_char) -> *mut c_char { - unimplemented!(); -} - -#[no_mangle] -pub extern "C" fn cuserid(s: *mut c_char) -> *mut c_char { - unimplemented!(); -} - #[no_mangle] pub extern "C" fn dup(fildes: c_int) -> c_int { - unimplemented!(); + platform::dup(fildes) } #[no_mangle] pub extern "C" fn dup2(fildes: c_int, fildes2: c_int) -> c_int { - unimplemented!(); + platform::dup2(fildes, fildes2) } #[no_mangle] @@ -131,12 +121,12 @@ pub extern "C" fn execvp(file: *const c_char, argv: *const *mut c_char) -> c_int #[no_mangle] pub extern "C" fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int { - unimplemented!(); + platform::fchown(fildes, owner, group) } #[no_mangle] pub extern "C" fn fchdir(fildes: c_int) -> c_int { - unimplemented!(); + platform::fchdir(fildes) } #[no_mangle] @@ -156,17 +146,17 @@ pub extern "C" fn fpathconf(fildes: c_int, name: c_int) -> c_long { #[no_mangle] pub extern "C" fn fsync(fildes: c_int) -> c_int { - unimplemented!(); + platform::fsync(fildes) } #[no_mangle] pub extern "C" fn ftruncate(fildes: c_int, length: off_t) -> c_int { - unimplemented!(); + platform::ftruncate(fildes, length) } #[no_mangle] pub extern "C" fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char { - unimplemented!(); + platform::getcwd(buf, size) } #[no_mangle] @@ -176,17 +166,17 @@ pub extern "C" fn getdtablesize() -> c_int { #[no_mangle] pub extern "C" fn getegid() -> gid_t { - unimplemented!(); + platform::getegid() } #[no_mangle] pub extern "C" fn geteuid() -> uid_t { - unimplemented!(); + platform::geteuid() } #[no_mangle] pub extern "C" fn getgid() -> gid_t { - unimplemented!(); + platform::getgid() } #[no_mangle] @@ -226,7 +216,7 @@ pub extern "C" fn getpass(prompt: *const c_char) -> *mut c_char { #[no_mangle] pub extern "C" fn getpgid(pid: pid_t) -> pid_t { - unimplemented!(); + platform::getpgid(pid) } #[no_mangle] @@ -236,12 +226,12 @@ pub extern "C" fn getpgrp() -> pid_t { #[no_mangle] pub extern "C" fn getpid() -> pid_t { - unimplemented!(); + platform::getpid() } #[no_mangle] pub extern "C" fn getppid() -> pid_t { - unimplemented!(); + platform::getppid() } #[no_mangle] @@ -251,7 +241,7 @@ pub extern "C" fn getsid(pid: pid_t) -> pid_t { #[no_mangle] pub extern "C" fn getuid() -> uid_t { - unimplemented!(); + platform::getuid() } #[no_mangle] @@ -271,7 +261,7 @@ pub extern "C" fn lchown(path: *const c_char, owner: uid_t, group: gid_t) -> c_i #[no_mangle] pub extern "C" fn link(path1: *const c_char, path2: *const c_char) -> c_int { - unimplemented!(); + platform::link(path1, path2) } #[no_mangle] diff --git a/tests/.gitignore b/tests/.gitignore index 45f2b7aa2e..759d9904ee 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,7 +1,18 @@ /alloc /args +/brk +/chdir /create /create.out +/dup +/dup.out +/fchdir +/fsync +/ftruncate +/ftruncate.out +/getid +/link +/link.out /math /printf /write diff --git a/tests/Makefile b/tests/Makefile index f3a5ff7366..77f7345de4 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,7 +1,15 @@ BINS=\ alloc \ + brk \ args \ + chdir \ create \ + dup \ + fchdir \ + fsync \ + ftruncate \ + getid \ + link \ math \ printf \ write diff --git a/tests/alloc.c b/tests/alloc.c index 99f11ff75f..a9fee5ee1b 100644 --- a/tests/alloc.c +++ b/tests/alloc.c @@ -9,4 +9,12 @@ int main(int argc, char ** argv) { ptr[i] = (char)i; } free(ptr); + + char * ptrc = (char *)calloc(256,1); + printf("calloc %p\n", ptrc); + for(int i = 0; i < 256; i++) { + ptrc[i] = (char)i; + } + free(ptrc); + } diff --git a/tests/brk.c b/tests/brk.c new file mode 100644 index 0000000000..a6f1e358fc --- /dev/null +++ b/tests/brk.c @@ -0,0 +1,8 @@ +#include +#include + +int main(int argc, char** argv) { + int status = brk((void*)100); + printf("brk exited with status code %d\n", status); +} + diff --git a/tests/chdir.c b/tests/chdir.c new file mode 100644 index 0000000000..38eb446708 --- /dev/null +++ b/tests/chdir.c @@ -0,0 +1,15 @@ +#include +#include +#include + +int main(int argc, char** argv) { + char* cwd1 = malloc(4096*sizeof(char));//(char*) calloc(4096 + 1, sizeof(char)); + getcwd(cwd1, 4096); + printf("initial cwd: %s\n", cwd1); + free(cwd1); + chdir(".."); + char* cwd2 = malloc(4096*sizeof(char));//(char*) calloc(4096 + 1, sizeof(char)); + getcwd(cwd2, 4096); + printf("final cwd: %s\n", cwd2); + free(cwd2); +} diff --git a/tests/dup.c b/tests/dup.c new file mode 100644 index 0000000000..1a5a32555b --- /dev/null +++ b/tests/dup.c @@ -0,0 +1,16 @@ +#include +#include +#include + +int main(int argc, char** argv) { + creat("dup.out", 0777); + int fd1 = open("dup.out", 0, 0); + int fd2 = dup(fd1); + printf("fd %d duped into fd %d\n", fd1, fd2); + close(fd1); + close(fd2); + int fd3 = open("dup.out", 0x0002, 0x1000); + dup2(fd3, 1); + printf("hello fd %d", fd3); + close(fd3); +} diff --git a/tests/fchdir.c b/tests/fchdir.c new file mode 100644 index 0000000000..b778642324 --- /dev/null +++ b/tests/fchdir.c @@ -0,0 +1,11 @@ +#include +#include +#include + +int main (int argc, char** argv) { + int fd = open("..", 0, 0); + int status; + status = fchdir(fd); + printf("fchdir exited with status code %d\n", status); + close(fd); +} diff --git a/tests/fsync.c b/tests/fsync.c new file mode 100644 index 0000000000..a86887185e --- /dev/null +++ b/tests/fsync.c @@ -0,0 +1,11 @@ +#include +#include +#include + +int main (int argc, char** argv) { + int fd = open(".", 0, 0); + int status; + status = fsync(fd); + printf("fsync exited with status code %d\n", status); + close(fd); +} diff --git a/tests/ftruncate.c b/tests/ftruncate.c new file mode 100644 index 0000000000..7dc4b90d82 --- /dev/null +++ b/tests/ftruncate.c @@ -0,0 +1,11 @@ +#include +#include +#include + +int main (int argc, char** argv) { + int fd = creat("ftruncate.out", 0777); + int status; + status = ftruncate(fd, 100); + printf("ftruncate exited with status code %d\n", status); + close(fd); +} diff --git a/tests/getid.c b/tests/getid.c new file mode 100644 index 0000000000..f461884d39 --- /dev/null +++ b/tests/getid.c @@ -0,0 +1,14 @@ +#include +#include + +int main(int argc, char** argv) { + gid_t egid = getegid(); + uid_t euid = geteuid(); + gid_t gid = getgid(); + pid_t pgid = getpgid(0); + pid_t pid = getpid(); + pid_t ppid = getppid(); + uid_t uid = getuid(); + printf("egid: %d, euid: %d, gid: %d, pgid: %d, pid: %d, ppid %d, uid %d\n", + egid, euid, gid, pgid, pid, ppid, uid); +} diff --git a/tests/link.c b/tests/link.c new file mode 100644 index 0000000000..3e36df81fb --- /dev/null +++ b/tests/link.c @@ -0,0 +1,5 @@ +#include + +int main(int argc, char** argv) { + int status = link("link.c", "link.out"); +}