Browse Source

Merge pull request #14 from sajattack/unistd

implement some unistd
Jeremy Soller 7 years ago
parent
commit
a808dfe39c
16 changed files with 362 additions and 36 deletions
  1. 113 0
      platform/src/linux/mod.rs
  2. 27 0
      platform/src/rawfile.rs
  3. 86 1
      platform/src/redox/mod.rs
  4. 0 7
      src/stdio/src/lib.rs
  5. 18 28
      src/unistd/src/lib.rs
  6. 11 0
      tests/.gitignore
  7. 8 0
      tests/Makefile
  8. 8 0
      tests/alloc.c
  9. 8 0
      tests/brk.c
  10. 15 0
      tests/chdir.c
  11. 16 0
      tests/dup.c
  12. 11 0
      tests/fchdir.c
  13. 11 0
      tests/fsync.c
  14. 11 0
      tests/ftruncate.c
  15. 14 0
      tests/getid.c
  16. 5 0
      tests/link.c

+ 113 - 0
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 {

+ 27 - 0
platform/src/rawfile.rs

@@ -0,0 +1,27 @@
+use core::ops::Deref;
+
+pub struct RawFile(usize);
+
+impl RawFile {
+    pub fn open<T: AsRef<[u8]>>(path: T, flags: usize) -> Result<RawFile> {
+        open(path, flags).map(RawFile)
+    }
+
+    pub fn dup(&self, buf: &[u8]) -> Result<RawFile> {
+        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
+    }
+}

+ 86 - 1
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

+ 0 - 7
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 {

+ 18 - 28
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]

+ 11 - 0
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

+ 8 - 0
tests/Makefile

@@ -1,7 +1,15 @@
 BINS=\
 	alloc \
+	brk \
 	args \
+	chdir \
 	create \
+	dup \
+	fchdir \
+	fsync \
+	ftruncate \
+	getid \
+	link \
 	math \
 	printf \
 	write

+ 8 - 0
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);
+
 }

+ 8 - 0
tests/brk.c

@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include <stdio.h>
+
+int main(int argc, char** argv) {
+    int status = brk((void*)100);
+    printf("brk exited with status code %d\n", status);
+}
+

+ 15 - 0
tests/chdir.c

@@ -0,0 +1,15 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+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);
+}

+ 16 - 0
tests/dup.c

@@ -0,0 +1,16 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+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);
+}

+ 11 - 0
tests/fchdir.c

@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+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);
+}

+ 11 - 0
tests/fsync.c

@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+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);
+}

+ 11 - 0
tests/ftruncate.c

@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+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);
+}

+ 14 - 0
tests/getid.c

@@ -0,0 +1,14 @@
+#include <unistd.h>
+#include <stdio.h>
+
+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);
+}

+ 5 - 0
tests/link.c

@@ -0,0 +1,5 @@
+#include <unistd.h>
+
+int main(int argc, char** argv) {
+    int status = link("link.c", "link.out");
+}