Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

exec functions #76

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions include/bits/exec.h
Original file line number Diff line number Diff line change
@@ -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 changes: 3 additions & 0 deletions src/platform/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 8,6 @@ sc = "0.2"

[target.'cfg(target_os = "redox")'.dependencies]
redox_syscall = "0.1"

[dependencies]
ralloc = { path = "../../ralloc" }
11 changes: 11 additions & 0 deletions src/platform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"))]
Expand All @@ -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]
Expand All @@ -54,6 61,10 @@ pub unsafe fn c_str_n(s: *const c_char, n: usize) -> &'static [u8] {
slice::from_raw_parts(s as *const u8, size as usize)
}

pub unsafe fn cstr_from_bytes_with_nul_unchecked(bytes: &[u8]) -> *const c_char {
bytes.as_ptr() as *const c_char
}

pub struct FileWriter(pub c_int);

impl FileWriter {
Expand Down
4 changes: 4 additions & 0 deletions src/platform/src/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 48,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);
Expand Down
53 changes: 53 additions & 0 deletions src/platform/src/redox/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 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;
Expand Down Expand Up @@ -48,6 49,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'=') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will also probably want to make sure that the value isn't just an = or one side isn't empty.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is true, empty env values are expected

// 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) -> ! {
syscall::exit(status as usize);
loop {}
Expand Down
4 changes: 0 additions & 4 deletions src/stdlib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 2,6 @@

#![no_std]
#![feature(core_intrinsics)]
#![feature(global_allocator)]

extern crate ctype;
extern crate errno;
Expand All @@ -16,9 15,6 @@ use rand::{Rng, SeedableRng, XorShiftRng};
use errno::*;
use platform::types::*;

#[global_allocator]
static ALLOCATOR: ralloc::Allocator = ralloc::Allocator;

pub const EXIT_FAILURE: c_int = 1;
pub const EXIT_SUCCESS: c_int = 0;
pub const RAND_MAX: c_int = 2147483647;
Expand Down
3 changes: 2 additions & 1 deletion src/unistd/cbindgen.toml
Original file line number Diff line number Diff line change
@@ -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]
Expand Down
1 change: 0 additions & 1 deletion src/unistd/src/getopt.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
26 changes: 17 additions & 9 deletions src/unistd/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 8,7 @@ extern crate string;

pub use platform::types::*;
pub use getopt::*;

use core::ptr;

mod getopt;
Expand All @@ -30,6 31,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)
Expand Down Expand Up @@ -96,23 100,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]
Expand All @@ -121,7 129,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]
Expand Down Expand Up @@ -347,7 355,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]
Expand Down Expand Up @@ -377,7 385,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]
Expand Down
1 change: 1 addition & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 10,7 @@
/ctype
/dup
/error
/exec
/fchdir
/fcntl
/fsync
Expand Down
1 change: 1 addition & 0 deletions tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 8,7 @@ EXPECT_BINS=\
ctype \
dup \
error \
exec \
fchdir \
fcntl \
fsync \
Expand Down
8 changes: 8 additions & 0 deletions tests/exec.c
Original file line number Diff line number Diff line change
@@ -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;
}