Merge branch 'unistd' into 'master'

Exec Functions (again) (again)

See merge request redox-os/relibc!144
This commit is contained in:
Jeremy Soller
2018-06-28 19:24:04 +00:00
12 changed files with 144 additions and 12 deletions
+47
View File
@@ -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
View File
@@ -8,3 +8,6 @@ sc = "0.2"
[target.'cfg(target_os = "redox")'.dependencies]
redox_syscall = "0.1"
[dependencies]
ralloc = { path = "../../ralloc" }
+7
View File
@@ -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
View File
@@ -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
View File
@@ -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 {}
-1
View File
@@ -2,7 +2,6 @@
#![no_std]
#![feature(core_intrinsics)]
#![feature(global_allocator)]
extern crate ctype;
extern crate errno;
+2 -1
View File
@@ -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]
-1
View File
@@ -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
View File
@@ -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
View File
@@ -11,6 +11,7 @@
/ctype
/dup
/error
/exec
/fchdir
/fcntl
/fsync
+1
View File
@@ -9,6 +9,7 @@ EXPECT_BINS=\
ctype \
dup \
error \
exec \
fchdir \
fcntl \
fsync \
+8
View File
@@ -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;
}