소스 검색

Merge branch 'master' of https://github.com/redox-os/relibc

MggMuggins 7 년 전
부모
커밋
42de0a0a46
11개의 변경된 파일87개의 추가작업 그리고 7개의 파일을 삭제
  1. 1 0
      Cargo.lock
  2. 1 1
      README.md
  3. 12 0
      src/platform/src/linux/mod.rs
  4. 16 0
      src/platform/src/redox/mod.rs
  5. 1 0
      src/stdio/Cargo.toml
  6. 15 3
      src/stdio/src/lib.rs
  7. 5 3
      src/unistd/src/lib.rs
  8. 1 0
      tests/.gitignore
  9. 1 0
      tests/Makefile
  10. 1 0
      tests/error.c
  11. 33 0
      tests/pipe.c

+ 1 - 0
Cargo.lock

@@ -445,6 +445,7 @@ name = "stdio"
 version = "0.1.0"
 dependencies = [
  "cbindgen 0.5.0",
+ "errno 0.1.0",
  "platform 0.1.0",
  "va_list 0.1.0",
 ]

+ 1 - 1
README.md

@@ -1,2 +1,2 @@
 # relibc
-C Library in Rust for Redox and Linux (WIP)
+relibc is a portable POSIX C standard library written in Rust. It is under heavy development, and currently supports Redox and Linux.

+ 12 - 0
src/platform/src/linux/mod.rs

@@ -62,6 +62,10 @@ pub fn fchdir(fildes: c_int) -> c_int {
     e(unsafe { syscall!(FCHDIR, fildes) }) as c_int
 }
 
+pub fn fork() -> pid_t {
+    e(unsafe {syscall!(FORK) }) as pid_t
+}
+
 pub fn fsync(fildes: c_int) -> c_int {
     e(unsafe { syscall!(FSYNC, fildes) }) as c_int
 }
@@ -114,6 +118,14 @@ pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
     e(unsafe { syscall!(OPENAT, AT_FDCWD, path, oflag, mode) }) as c_int
 }
 
+pub fn pipe(fildes: [c_int; 2]) -> c_int {
+    e(unsafe { syscall!(PIPE2, fildes.as_ptr(), 0) }) as c_int
+}
+
+pub fn read(fildes: c_int, buf: &[u8]) -> ssize_t {
+    e(unsafe { syscall!(READ, fildes, buf.as_ptr(), buf.len()) }) as ssize_t
+}
+
 pub fn write(fildes: c_int, buf: &[u8]) -> ssize_t {
     e(unsafe { syscall!(WRITE, fildes, buf.as_ptr(), buf.len()) }) as ssize_t
 }

+ 16 - 0
src/platform/src/redox/mod.rs

@@ -63,6 +63,10 @@ pub fn fchdir(fd: c_int) -> c_int {
     }
 }
 
+pub fn fork() -> pid_t {
+   e(unsafe { syscall::clone(0) }) as pid_t
+}
+
 pub fn fsync(fd: c_int) -> c_int {
     e(syscall::fsync(fd as usize)) as c_int
 }
@@ -119,6 +123,18 @@ pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
     e(syscall::open(path, (oflag as usize) | (mode as usize))) as c_int
 }
 
+pub fn pipe(fds: [c_int; 2]) -> c_int {
+    let mut usize_fds: [usize; 2] = [0; 2];
+    let res = e(syscall::pipe2(&mut usize_fds));
+    fds[0] = usize_fds[0] as c_int;
+    fds[1] = usize_fds[1] as c_int;
+    res as c_int
+}
+
+pub fn read(fd: c_int, buf: &mut [u8]) -> ssize_t {
+    e(syscall::read(fd as usize, buf)) as ssize_t
+}
+
 pub fn write(fd: c_int, buf: &[u8]) -> ssize_t {
     e(syscall::write(fd as usize, buf)) as ssize_t
 }

+ 1 - 0
src/stdio/Cargo.toml

@@ -10,3 +10,4 @@ cbindgen = { path = "../../cbindgen" }
 [dependencies]
 platform = { path = "../platform" }
 va_list = { path = "../../va_list", features = ["no_std"] }
+errno = { path = "../errno"}

+ 15 - 3
src/stdio/src/lib.rs

@@ -4,10 +4,15 @@
 
 extern crate platform;
 extern crate va_list as vl;
+extern crate errno;
 
-use core::slice;
+use core::str;
+use core::fmt::Write;
 
 use platform::types::*;
+use platform::c_str;
+use platform::errno;
+use errno::STR_ERROR;
 use vl::VaList as va_list;
 
 mod printf;
@@ -203,8 +208,15 @@ pub extern "C" fn pclose(stream: *mut FILE) -> c_int {
 }
 
 #[no_mangle]
-pub extern "C" fn perror(s: *const c_char) {
-    unimplemented!();
+pub unsafe extern "C" fn perror(s: *const c_char) {
+    let s_str = str::from_utf8_unchecked(c_str(s));
+
+    let mut w = platform::FileWriter(2);
+    if errno >= 0 && errno < STR_ERROR.len() as c_int {
+        w.write_fmt(format_args!("{}: {}\n", s_str, STR_ERROR[errno as usize]));
+    } else {
+        w.write_fmt(format_args!("{}: Unknown error {}\n", s_str, errno));
+    }
 }
 
 #[no_mangle]

+ 5 - 3
src/unistd/src/lib.rs

@@ -140,7 +140,7 @@ pub extern "C" fn fdatasync(fildes: c_int) -> c_int {
 
 #[no_mangle]
 pub extern "C" fn fork() -> pid_t {
-    unimplemented!();
+    platform::fork()
 }
 
 #[no_mangle]
@@ -295,7 +295,7 @@ pub extern "C" fn pause() -> c_int {
 
 #[no_mangle]
 pub extern "C" fn pipe(fildes: [c_int; 2]) -> c_int {
-    unimplemented!();
+    platform::pipe(fildes)
 }
 
 #[no_mangle]
@@ -324,7 +324,9 @@ pub extern "C" fn pwrite(
 
 #[no_mangle]
 pub extern "C" fn read(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t {
-    unimplemented!();
+    use core::slice;
+    let buf = unsafe { slice::from_raw_parts_mut(buf as *mut u8, nbyte as usize) };
+    platform::read(fildes, buf)
 }
 
 #[no_mangle]

+ 1 - 0
tests/.gitignore

@@ -17,5 +17,6 @@
 /link
 /link.out
 /math
+/pipe
 /printf
 /write

+ 1 - 0
tests/Makefile

@@ -14,6 +14,7 @@ BINS=\
 	getid \
 	link \
 	math \
+	pipe \
 	printf \
 	write
 

+ 1 - 0
tests/error.c

@@ -6,4 +6,5 @@
 int main(int argc, char** argv) {
     chdir("nonexistent");
     printf("errno: %d = %s\n", errno, strerror(errno));
+    perror("perror");
 }

+ 33 - 0
tests/pipe.c

@@ -0,0 +1,33 @@
+//http://www2.cs.uregina.ca/~hamilton/courses/330/notes/unix/pipes/pipes.html
+#include <string.h>
+#include <unistd.h>
+
+int main()
+{
+
+    int pid, pip[2];
+    char instring[20];
+    char * outstring = "Hello World!";
+
+    pipe(pip);
+
+    pid = fork();
+    if (pid == 0)           /* child : sends message to parent*/
+    {
+        /* close read end */
+        close(pip[0]);
+        /* send 7 characters in the string, including end-of-string */
+        write(pip[1], outstring, strlen(outstring));
+        /* close write end */
+        close(pip[1]);
+    }
+    else			/* parent : receives message from child */
+    {
+        /* close write end */
+        close(pip[1]);
+        /* read from the pipe */
+        read(pip[0], instring, 7);
+        /* close read end */
+        close(pip[0]);
+    }
+}