浏览代码

Implement argument handling, add string.h

Jeremy Soller 7 年之前
父节点
当前提交
2aff4d41dd
共有 15 个文件被更改,包括 132 次插入27 次删除
  1. 9 0
      Cargo.lock
  2. 1 0
      Cargo.toml
  3. 23 4
      crt0/src/lib.rs
  4. 12 0
      include/stddef.h
  5. 0 1
      include/sys/types.h
  6. 1 3
      src/lib.rs
  7. 11 0
      string/Cargo.toml
  8. 11 0
      string/build.rs
  9. 6 0
      string/cbindgen.toml
  10. 28 0
      string/src/lib.rs
  11. 1 0
      tests/.gitignore
  12. 3 2
      tests/Makefile
  13. 11 0
      tests/args.c
  14. 1 1
      unistd/cbindgen.toml
  15. 14 16
      unistd/src/lib.rs

+ 9 - 0
Cargo.lock

@@ -199,6 +199,7 @@ dependencies = [
  "compiler_builtins 0.1.0 (git+https://github.com/rust-lang-nursery/compiler-builtins.git)",
  "fcntl 0.1.0",
  "platform 0.1.0",
+ "string 0.1.0",
  "unistd 0.1.0",
 ]
 
@@ -364,6 +365,14 @@ dependencies = [
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "string"
+version = "0.1.0"
+dependencies = [
+ "cbindgen 0.5.0",
+ "platform 0.1.0",
+]
+
 [[package]]
 name = "strsim"
 version = "0.7.0"

+ 1 - 0
Cargo.toml

@@ -14,6 +14,7 @@ members = ["crt0"]
 compiler_builtins = { git = "https://github.com/rust-lang-nursery/compiler-builtins.git", default-features = false, features = ["mem"] }
 platform = { path = "platform" }
 fcntl = { path = "fcntl" }
+string = { path = "string" }
 unistd = { path = "unistd" }
 
 [profile.dev]

+ 23 - 4
crt0/src/lib.rs

@@ -17,18 +17,37 @@ pub unsafe extern "C" fn _start() {
         :
         :
         :
-        : "intel"
+        : "intel", "volatile"
     );
 }
 
+#[repr(C)]
+pub struct Stack {
+    argc: isize,
+    argv0: *const u8,
+}
+
+impl Stack {
+    fn argc(&self) -> isize {
+        self.argc
+    }
+
+    fn argv(&self) -> *const *const u8 {
+        &self.argv0 as *const *const u8
+    }
+}
+
 #[inline(never)]
 #[no_mangle]
-pub unsafe extern "C" fn _start_rust(sp: usize) -> ! {
+pub unsafe extern "C" fn _start_rust(sp: &'static Stack) -> ! {
     extern "C" {
-        fn main(argc: c_int, argv: *const *const c_char) -> c_int;
+        fn main(argc: isize, argv: *const *const u8) -> c_int;
     }
 
-    platform::exit(main(0, 0 as *const *const c_char));
+    let argc = sp.argc();
+    let argv = sp.argv();
+
+    platform::exit(main(argc, argv));
 }
 
 #[lang = "panic_fmt"]

+ 12 - 0
include/stddef.h

@@ -0,0 +1,12 @@
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+#define NULL 0
+
+typedef signed long long ptrdiff_t;
+
+typedef unsigned char wchar_t;
+
+typedef unsigned long long size_t;
+
+#endif /* _STDDEF_H */

+ 0 - 1
include/sys/types.h

@@ -10,7 +10,6 @@ typedef long off_t;
 
 typedef int pid_t;
 
-typedef unsigned long size_t;
 typedef long ssize_t;
 
 typedef int useconds_t;

+ 1 - 3
src/lib.rs

@@ -5,11 +5,9 @@ extern crate compiler_builtins;
 extern crate platform;
 
 extern crate fcntl;
+extern crate string;
 extern crate unistd;
 
-pub use fcntl::*;
-pub use unistd::*;
-
 use core::fmt;
 
 struct PanicWriter;

+ 11 - 0
string/Cargo.toml

@@ -0,0 +1,11 @@
+[package]
+name = "string"
+version = "0.1.0"
+authors = ["Jeremy Soller <jackpot51@gmail.com>"]
+build = "build.rs"
+
+[build-dependencies]
+cbindgen = { path = "../cbindgen" }
+
+[dependencies]
+platform = { path = "../platform" }

+ 11 - 0
string/build.rs

@@ -0,0 +1,11 @@
+extern crate cbindgen;
+
+use std::{env, fs};
+
+fn main() {
+    let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
+    fs::create_dir_all("../target/include").expect("failed to create include directory");
+    cbindgen::generate(crate_dir)
+      .expect("failed to generate bindings")
+      .write_to_file("../target/include/string.h");
+}

+ 6 - 0
string/cbindgen.toml

@@ -0,0 +1,6 @@
+sys_includes = ["stddef.h"]
+include_guard = "_STRING_H"
+language = "C"
+
+[enum]
+prefix_with_name = true

+ 28 - 0
string/src/lib.rs

@@ -0,0 +1,28 @@
+//! string implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/string.h.html
+
+#![no_std]
+
+extern crate platform;
+
+use platform::types::*;
+
+#[no_mangle]
+pub unsafe extern "C" fn strlen(s: *const c_char) -> size_t {
+    let mut size = 0;
+
+    loop {
+        if *s.offset(size) == 0 {
+            break;
+        }
+        size += 1;
+    }
+
+    size as size_t
+}
+
+/*
+#[no_mangle]
+pub extern "C" fn func(args) -> c_int {
+    unimplemented!();
+}
+*/

+ 1 - 0
tests/.gitignore

@@ -1,3 +1,4 @@
+/args
 /create
 /create.out
 /write

+ 3 - 2
tests/Makefile

@@ -1,14 +1,15 @@
 BINS=\
+	args \
 	create \
 	write
 
 all: $(BINS)
 
 clean:
-	rm -f $(BINS)
+	rm -f $(BINS) *.out
 
 run: $(BINS)
-	for bin in $(BINS); do echo "\\033[1m$${bin}\\033[0m"; ./$${bin}; done
+	for bin in $(BINS); do echo "\\033[1m$${bin}\\033[0m"; ./$${bin} test args; done
 
 %: %.c
 	gcc -nostdinc -nostdlib -I ../include -I ../target/include ../target/debug/libcrt0.a $< ../target/debug/libc.a -o $@

+ 11 - 0
tests/args.c

@@ -0,0 +1,11 @@
+#include <string.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+    int i;
+    for(i = 0; i < argc; i++) {
+        write(STDOUT_FILENO, argv[i], strlen(argv[i]));
+        write(STDOUT_FILENO, " ", 1);
+    }
+    write(STDOUT_FILENO, "\n", 1);
+}

+ 1 - 1
unistd/cbindgen.toml

@@ -1,4 +1,4 @@
-sys_includes = ["stdint.h", "sys/types.h"]
+sys_includes = ["stddef.h", "stdint.h", "sys/types.h"]
 include_guard = "_UNISTD_H"
 language = "C"
 

+ 14 - 16
unistd/src/lib.rs

@@ -6,8 +6,6 @@ extern crate platform;
 
 pub use platform::types::*;
 
-pub const NULL: c_int = 0;
-
 pub const R_OK: c_int = 1;
 pub const W_OK: c_int = 2;
 pub const X_OK: c_int = 4;
@@ -101,20 +99,20 @@ pub extern "C" fn encrypt(block: [c_char; 64], edflag: c_int) {
     unimplemented!();
 }
 
-#[no_mangle]
-pub extern "C" fn execl(path: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int {
-    unimplemented!();
-}
-
-#[no_mangle]
-pub extern "C" fn execle(path: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int {
-    unimplemented!();
-}
-
-#[no_mangle]
-pub extern "C" fn execlp(file: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int {
-    unimplemented!();
-}
+// #[no_mangle]
+// pub extern "C" fn execl(path: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int {
+//     unimplemented!();
+// }
+//
+// #[no_mangle]
+// pub extern "C" fn execle(path: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int {
+//     unimplemented!();
+// }
+//
+// #[no_mangle]
+// pub extern "C" fn execlp(file: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int {
+//     unimplemented!();
+// }
 
 #[no_mangle]
 pub extern "C" fn execv(path: *const c_char, argv: *const *mut c_char) -> c_int {