Ver código fonte

Merge branch 'unistd' into 'master'

Exec Functions (again) (again)

See merge request redox-os/relibc!144
Jeremy Soller 6 anos atrás
pai
commit
29a626cd7c

+ 47 - 0
include/bits/exec.h

@@ -0,0 +1,47 @@
+#ifndef _BITS_EXEC_H
+#define _BITS_EXEC_H
+
+int execl(const char *path, const char* argv0, ...)
+{
+	int argc;
+	va_list ap;
+	va_start(ap, argv0);
+	for (argc = 1; va_arg(ap, const char*); argc++);
+	va_end(ap);
+	{
+		int i;
+		char *argv[argc+1];
+		va_start(ap, argv0);
+		argv[0] = (char *)argv0;
+		for (i = 1; i < argc; i++) {
+			argv[i] = va_arg(ap, char *);
+		}
+		argv[i] = NULL;
+		va_end(ap);
+		return execv(path, argv);
+	}
+}
+
+int execle(const char *path, const char* argv0, ...)
+{
+	int argc;
+	va_list ap;
+	va_start(ap, argv0);
+	for (argc = 1; va_arg(ap, const char *); argc++);
+	va_end(ap);
+	{
+		int i;
+		char *argv[argc+1];
+		char **envp;
+		va_start(ap, argv0);
+		argv[0] = (char *)argv0;
+		for (i = 1; i <= argc; i++) {
+			argv[i] = va_arg(ap, char *);
+		}
+		envp = va_arg(ap, char **);
+		va_end(ap);
+		return execve(path, argv, envp);
+	}
+}
+
+#endif

+ 3 - 0
src/platform/Cargo.toml

@@ -8,3 +8,6 @@ sc = "0.2"
 
 [target.'cfg(target_os = "redox")'.dependencies]
 redox_syscall = "0.1"
+
+[dependencies]
+ralloc = { path = "../../ralloc" }

+ 7 - 0
src/platform/src/lib.rs

@@ -2,6 +2,8 @@
 
 #![no_std]
 #![allow(non_camel_case_types)]
+#![feature(alloc)]
+#![feature(global_allocator)]
 //TODO #![feature(thread_local)]
 
 #[cfg(all(not(feature = "no_std"), target_os = "linux"))]
@@ -22,12 +24,17 @@ mod sys;
 #[path = "redox/mod.rs"]
 mod sys;
 
+extern crate alloc;
+extern crate ralloc;
+
 pub mod types;
 
 use core::fmt;
 
 use types::*;
 
+#[global_allocator]
+static ALLOCATOR: ralloc::Allocator = ralloc::Allocator;
 //TODO #[thread_local]
 #[allow(non_upper_case_globals)]
 #[no_mangle]

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

@@ -54,6 +54,10 @@ pub fn dup2(fildes: c_int, fildes2: c_int) -> c_int {
     e(unsafe { syscall!(DUP3, fildes, fildes2, 0) }) as c_int
 }
 
+pub fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
+    e(unsafe { syscall!(EXECVE, path, argv, envp) }) as c_int
+}
+
 pub fn exit(status: c_int) -> ! {
     unsafe {
         syscall!(EXIT, status);

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

@@ -1,5 +1,7 @@
 use core::ptr;
 use core::slice;
+use core::mem;
+use alloc::Vec;
 use syscall;
 use syscall::flag::*;
 use syscall::data::TimeSpec as redox_timespec;
@@ -66,6 +68,58 @@ pub fn dup2(fd1: c_int, fd2: c_int) -> c_int {
     e(syscall::dup2(fd1 as usize, fd2 as usize, &[])) as c_int
 }
 
+pub fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
+    unsafe {
+        let mut env = envp;
+        while !(*env).is_null() {
+            let slice = c_str(*env);
+            // Should always contain a =, but worth checking
+            if let Some(sep) = slice.iter().position(|&c| c == b'=') {
+                // If the environment variable has no name, do not attempt
+                // to add it to the env.
+                if sep > 0 {
+                    let mut path = b"env:".to_vec();
+                    path.extend_from_slice(&slice[..sep]);
+                    match syscall::open(&path, O_WRONLY | O_CREAT) {
+                        Ok(fd) => {
+                            // If the environment variable has no value, there
+                            // is no need to write anything to the env scheme.
+                            if sep + 1 < slice.len() {
+                                let n = match syscall::write(fd, &slice[sep + 1..]) {
+                                    Ok(n) => n,
+                                    err => {
+                                        return e(err) as c_int;
+                                    }
+                                };
+                            }
+                            // Cleanup after adding the variable.
+                            match syscall::close(fd) {
+                                Ok(_) => (),
+                                err => {
+                                    return e(err) as c_int;
+                                }
+                            }
+                        }
+                        err => {
+                            return e(err) as c_int;
+                        }
+                    }
+                }
+            }
+            env = env.offset(1);
+        }
+
+        let mut args: Vec<[usize; 2]> = Vec::new();
+        let mut arg = argv;
+        while !(*arg).is_null() {
+            args.push([*arg as usize, c_str(*arg).len()]);
+            arg = arg.offset(1);
+        }
+
+        e(syscall::execve(c_str(path), &args)) as c_int
+    }
+}
+
 pub fn exit(status: c_int) -> ! {
     let _ = syscall::exit(status as usize);
     loop {}

+ 0 - 1
src/stdlib/src/lib.rs

@@ -2,7 +2,6 @@
 
 #![no_std]
 #![feature(core_intrinsics)]
-#![feature(global_allocator)]
 
 extern crate ctype;
 extern crate errno;

+ 2 - 1
src/unistd/cbindgen.toml

@@ -1,5 +1,6 @@
-sys_includes = ["stddef.h", "stdint.h", "sys/types.h"]
+sys_includes = ["stddef.h", "stdint.h", "sys/types.h", "stdarg.h", "bits/exec.h"]
 include_guard = "_UNISTD_H"
+trailer = "#include <bits/fcntl.h>"
 language = "C"
 
 [enum]

+ 0 - 1
src/unistd/src/getopt.rs

@@ -1,7 +1,6 @@
 //! getopt implementation for Redox, following http://pubs.opengroup.org/onlinepubs/009695399/functions/getopt.html
 
 use super::platform::types::*;
-use super::platform;
 use super::stdio;
 use super::string;
 use core::ptr;

+ 17 - 9
src/unistd/src/lib.rs

@@ -9,6 +9,7 @@ extern crate sys_utsname;
 
 pub use platform::types::*;
 pub use getopt::*;
+
 use core::ptr;
 
 mod getopt;
@@ -31,6 +32,9 @@ pub const STDIN_FILENO: c_int = 0;
 pub const STDOUT_FILENO: c_int = 1;
 pub const STDERR_FILENO: c_int = 2;
 
+#[no_mangle]
+pub static mut environ: *const *mut c_char = 0 as *const *mut c_char;
+
 #[no_mangle]
 pub extern "C" fn _exit(status: c_int) {
     platform::exit(status)
@@ -97,23 +101,27 @@ pub extern "C" fn encrypt(block: [c_char; 64], edflag: c_int) {
 }
 
 // #[no_mangle]
-// pub extern "C" fn execl(path: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int {
+// pub extern "C" fn execl(path: *const c_char, args: *const *mut c_char) -> c_int {
 //     unimplemented!();
 // }
-//
+
 // #[no_mangle]
-// pub extern "C" fn execle(path: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int {
+// pub extern "C" fn execle(
+//   path: *const c_char,
+//   args: *const *mut c_char,
+//   envp: *const *mut c_char,
+// ) -> c_int {
 //     unimplemented!();
 // }
-//
+
 // #[no_mangle]
-// pub extern "C" fn execlp(file: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int {
+// pub extern "C" fn execlp(file: *const c_char, args: *const *mut c_char) -> c_int {
 //     unimplemented!();
 // }
 
 #[no_mangle]
 pub extern "C" fn execv(path: *const c_char, argv: *const *mut c_char) -> c_int {
-    unimplemented!();
+    unsafe { execve(path, argv, environ) }
 }
 
 #[no_mangle]
@@ -122,7 +130,7 @@ pub extern "C" fn execve(
     argv: *const *mut c_char,
     envp: *const *mut c_char,
 ) -> c_int {
-    unimplemented!();
+    platform::execve(path, argv, envp)
 }
 
 #[no_mangle]
@@ -396,7 +404,7 @@ pub extern "C" fn sbrk(incr: intptr_t) -> *mut c_void {
 
 #[no_mangle]
 pub extern "C" fn setgid(gid: gid_t) -> c_int {
-    unimplemented!();
+    platform::setregid(gid, gid)
 }
 
 #[no_mangle]
@@ -426,7 +434,7 @@ pub extern "C" fn setsid() -> pid_t {
 
 #[no_mangle]
 pub extern "C" fn setuid(uid: uid_t) -> c_int {
-    unimplemented!();
+    platform::setreuid(uid, uid)
 }
 
 #[no_mangle]

+ 1 - 0
tests/.gitignore

@@ -11,6 +11,7 @@
 /ctype
 /dup
 /error
+/exec
 /fchdir
 /fcntl
 /fsync

+ 1 - 0
tests/Makefile

@@ -9,6 +9,7 @@ EXPECT_BINS=\
 	ctype \
 	dup \
 	error \
+	exec \
 	fchdir \
 	fcntl \
 	fsync \

+ 8 - 0
tests/exec.c

@@ -0,0 +1,8 @@
+#include <unistd.h>
+
+int main(int argc, char** argv) {
+    char *const args[1] = {"arg"};
+    execv("write", args);
+    perror("execv");
+    return 0;
+}