From ad704c421f083c207ff10de8fb246f184300042e Mon Sep 17 00:00:00 2001 From: "Tate, Hongliang Tian" Date: Tue, 8 Jan 2019 19:36:29 +0800 Subject: [PATCH] Add argc and argv support --- src/Enclave.edl | 2 +- src/libos/src/entry.rs | 82 ++++++++++++++++++++++++ src/libos/src/fs/pipe.rs | 8 +-- src/libos/src/lib.rs | 58 ++--------------- src/libos/src/syscall/mod.rs | 62 +++++-------------- src/libos/src/util/mem_util.rs | 110 +++++++++++++++++++++++++++++++++ src/libos/src/util/mod.rs | 9 +-- src/libos/src/util/ring_buf.rs | 18 ++++-- src/pal/pal.c | 8 +-- test/Makefile | 2 +- test/argv/Makefile | 14 +++++ test/argv/main.c | 30 +++++++++ test/empty/Makefile | 1 + test/file/Makefile | 1 + test/getpid/Makefile | 1 + test/hello_world/Makefile | 1 + test/malloc/Makefile | 1 + test/pipe/Makefile | 1 + test/spawn/Makefile | 1 + test/test_common.mk | 2 +- test/time/Makefile | 1 + 21 files changed, 290 insertions(+), 123 deletions(-) create mode 100644 src/libos/src/entry.rs create mode 100644 src/libos/src/util/mem_util.rs create mode 100644 test/argv/Makefile create mode 100644 test/argv/main.c diff --git a/src/Enclave.edl b/src/Enclave.edl index 07a84d84..d95b33af 100644 --- a/src/Enclave.edl +++ b/src/Enclave.edl @@ -7,7 +7,7 @@ enclave { trusted { /* define ECALLs here. */ - public int libos_boot([in, string] const char* executable_path); + public int libos_boot([in, string] const char* executable_path, [user_check] char** argv); public int libos_run(void); }; diff --git a/src/libos/src/entry.rs b/src/libos/src/entry.rs new file mode 100644 index 00000000..56949a57 --- /dev/null +++ b/src/libos/src/entry.rs @@ -0,0 +1,82 @@ +use super::{*}; +use util::mem_util::from_untrusted::*; +use std::ffi::{CStr, CString, OsString}; +use std::path::{Path}; + +#[no_mangle] +pub extern "C" fn libos_boot(path_buf: *const c_char, argv: *const *const c_char) -> i32 { + let (path, args) = match parse_arguments(path_buf, argv) { + Ok(path_and_args) => { + path_and_args + }, + Err(_) => { + return EXIT_STATUS_INTERNAL_ERROR; + } + }; + + let _ = backtrace::enable_backtrace("libocclum.signed.so", PrintFormat::Short); + panic::catch_unwind(||{ + backtrace::__rust_begin_short_backtrace(||{ + match do_boot(&path, &args) { + Ok(()) => 0, + Err(err) => EXIT_STATUS_INTERNAL_ERROR, + } + }) + }).unwrap_or(EXIT_STATUS_INTERNAL_ERROR) +} + +#[no_mangle] +pub extern "C" fn libos_run() -> i32 { + let _ = backtrace::enable_backtrace("libocclum.signed.so", PrintFormat::Short); + panic::catch_unwind(||{ + backtrace::__rust_begin_short_backtrace(||{ + match do_run() { + Ok(exit_status) => exit_status, + Err(err) => EXIT_STATUS_INTERNAL_ERROR, + } + }) + }).unwrap_or(EXIT_STATUS_INTERNAL_ERROR) +} + +// Use 127 as a special value to indicate internal error from libos, not from +// user programs, although it is completely ok for a user program to return 127. +const EXIT_STATUS_INTERNAL_ERROR : i32 = 127; + +fn parse_arguments(path_buf: *const c_char, argv: *const *const c_char) + -> Result<(String, Vec), Error> +{ + let path_string = { + let path_cstring = clone_cstring_safely(path_buf)?; + path_cstring.to_string_lossy().into_owned() + }; + let program_cstring = { + let program_osstr= Path::new(&path_string).file_name() + .ok_or_else(|| Error::new(Errno::EINVAL, "Invalid path"))?; + let program_str = program_osstr.to_str() + .ok_or_else(|| Error::new(Errno::EINVAL, "Invalid path"))?; + CString::new(program_str) + .or_else(|_| errno!(EINVAL, "Invalid path"))? + }; + + let mut args = clone_cstrings_safely(argv)?; + args.insert(0, program_cstring); + Ok((path_string, args)) +} + +// TODO: make sure do_boot can only be called once +fn do_boot(path_str: &str, argv: &Vec) -> Result<(), Error> { + util::mpx_util::mpx_enable()?; + + let envp = std::vec::Vec::new(); + let file_actions = Vec::new(); + let parent = &process::IDLE_PROCESS; + process::do_spawn(&path_str, argv, &envp, &file_actions, parent)?; + + Ok(()) +} + +// TODO: make sure do_run() cannot be called after do_boot() +fn do_run() -> Result { + let exit_status = process::run_task()?; + Ok(exit_status) +} diff --git a/src/libos/src/fs/pipe.rs b/src/libos/src/fs/pipe.rs index 57cd4099..7ee2f246 100644 --- a/src/libos/src/fs/pipe.rs +++ b/src/libos/src/fs/pipe.rs @@ -1,5 +1,5 @@ use super::*; -use util::{new_ring_buf, RingBufReader, RingBufWriter}; +use util::ring_buf::{*}; // TODO: Use Waiter and WaitQueue infrastructure to sleep when blocking @@ -13,13 +13,13 @@ pub struct Pipe { impl Pipe { pub fn new() -> Result { - let (reader, writer) = new_ring_buf(PIPE_BUF_SIZE); + let mut ring_buf = RingBuf::new(PIPE_BUF_SIZE); Ok(Pipe { reader: PipeReader { - inner: SgxMutex::new(reader), + inner: SgxMutex::new(ring_buf.reader), }, writer: PipeWriter { - inner: SgxMutex::new(writer), + inner: SgxMutex::new(ring_buf.writer), } }) } diff --git a/src/libos/src/lib.rs b/src/libos/src/lib.rs index 0adbc212..cc3d6bc4 100644 --- a/src/libos/src/lib.rs +++ b/src/libos/src/lib.rs @@ -26,6 +26,7 @@ use sgx_trts::libc; #[macro_use] mod prelude; +mod entry; mod errno; mod fs; mod process; @@ -36,58 +37,7 @@ mod time; use prelude::*; -/// Export system calls +// Export system calls pub use syscall::*; - -// TODO: return meaningful exit code -#[no_mangle] -pub extern "C" fn libos_boot(path_buf: *const i8) -> i32 { - let path_str = unsafe { - CStr::from_ptr(path_buf).to_string_lossy().into_owned() - }; - let _ = backtrace::enable_backtrace("libocclum.signed.so", PrintFormat::Short); - panic::catch_unwind(||{ - backtrace::__rust_begin_short_backtrace(||{ - match do_boot(&path_str) { - Ok(()) => 0, - Err(err) => EXIT_STATUS_INTERNAL_ERROR, - } - }) - }).unwrap_or(EXIT_STATUS_INTERNAL_ERROR) -} - -#[no_mangle] -pub extern "C" fn libos_run() -> i32 { - let _ = backtrace::enable_backtrace("libocclum.signed.so", PrintFormat::Short); - panic::catch_unwind(||{ - backtrace::__rust_begin_short_backtrace(||{ - match do_run() { - Ok(exit_status) => exit_status, - Err(err) => EXIT_STATUS_INTERNAL_ERROR, - } - }) - }).unwrap_or(EXIT_STATUS_INTERNAL_ERROR) -} - -// Use 127 as a special value to indicate internal error from libos, not from -// user programs, although it is completely ok for a user program to return 127. -const EXIT_STATUS_INTERNAL_ERROR : i32 = 127; - -// TODO: make sure do_boot can only be called once -fn do_boot(path_str: &str) -> Result<(), Error> { - util::mpx_enable()?; - - let argv = std::vec::Vec::new(); - let envp = std::vec::Vec::new(); - let file_actions = Vec::new(); - let parent = &process::IDLE_PROCESS; - process::do_spawn(&path_str, &argv, &envp, &file_actions, parent)?; - - Ok(()) -} - -// TODO: make sure do_run() cannot be called before do_boot() -fn do_run() -> Result { - let exit_status = process::run_task()?; - Ok(exit_status) -} +// Export ECalls +pub use entry::*; diff --git a/src/libos/src/syscall/mod.rs b/src/libos/src/syscall/mod.rs index e36a1471..c680ddef 100644 --- a/src/libos/src/syscall/mod.rs +++ b/src/libos/src/syscall/mod.rs @@ -7,6 +7,7 @@ use fs::{off_t, FileDesc}; use vm::{VMAreaFlags, VMResizeOptions}; use process::{pid_t, ChildProcessFilter, FileAction}; use time::{timeval_t}; +use util::mem_util::from_user::{*}; // Use the internal syscall wrappers from sgx_tstd //use std::libc_fs as fs; //use std::libc_io as io; @@ -17,39 +18,6 @@ pub struct iovec_t { len: size_t, } -fn check_ptr_from_user(user_ptr: *const T) -> Result<(), Error> { - Ok(()) -} - -fn check_mut_ptr_from_user(user_ptr: *mut T) -> Result<(), Error> { - Ok(()) -} - -fn check_array_from_user(user_buf: *const T, count: usize) -> Result<(), Error> { - Ok(()) -} - -fn check_mut_array_from_user(user_buf: *mut T, count: usize) -> Result<(), Error> { - Ok(()) -} - -fn clone_cstring_from_user_safely(user_ptr: *const c_char) - -> Result -{ - check_ptr_from_user(user_ptr)?; - let string = unsafe { - CStr::from_ptr(user_ptr).to_string_lossy().into_owned() - }; - Ok(string) -} - -fn clone_cstrings_from_user_safely(user_ptr: *const *const c_char) - -> Result, Error> -{ - let cstrings = Vec::new(); - Ok(cstrings) -} - /* * This Rust-version of fdop correspond to the C-version one in Occlum. @@ -73,14 +41,14 @@ pub struct FdOp { path: *const u8, } -fn clone_file_actions_from_user_safely(fdop_ptr: *const FdOp) +fn clone_file_actions_safely(fdop_ptr: *const FdOp) -> Result, Error> { let mut file_actions = Vec::new(); let mut fdop_ptr = fdop_ptr; while fdop_ptr != ptr::null() { - check_ptr_from_user(fdop_ptr)?; + check_ptr(fdop_ptr)?; let fdop = unsafe { &*fdop_ptr }; let file_action = match fdop.cmd { @@ -113,11 +81,11 @@ fn do_spawn(child_pid_ptr: *mut c_uint, ) -> Result<(), Error> { - check_mut_ptr_from_user(child_pid_ptr)?; - let path = clone_cstring_from_user_safely(path)?; - let argv = clone_cstrings_from_user_safely(argv)?; - let envp = clone_cstrings_from_user_safely(envp)?; - let file_actions = clone_file_actions_from_user_safely(fdop_list)?; + check_mut_ptr(child_pid_ptr)?; + let path = clone_cstring_safely(path)?.to_string_lossy().into_owned(); + let argv = clone_cstrings_safely(argv)?; + let envp = clone_cstrings_safely(envp)?; + let file_actions = clone_file_actions_safely(fdop_list)?; let parent = process::get_current(); let child_pid = process::do_spawn(&path, &argv, &envp, &file_actions, &parent)?; @@ -133,7 +101,7 @@ fn do_read(fd: c_int, buf: *mut c_void, size: size_t) let safe_buf = { let buf = buf as *mut u8; let size = size as usize; - check_mut_array_from_user(buf, size)?; + check_mut_array(buf, size)?; unsafe { std::slice::from_raw_parts_mut(buf, size) } }; fs::do_read(fd, safe_buf) @@ -146,7 +114,7 @@ fn do_write(fd: c_int, buf: *const c_void, size: size_t) let safe_buf = { let buf = buf as *mut u8; let size = size as usize; - check_array_from_user(buf, size)?; + check_array(buf, size)?; unsafe { std::slice::from_raw_parts(buf, size) } }; fs::do_write(fd, safe_buf) @@ -164,7 +132,7 @@ fn do_writev(fd: c_int, iov: *const iovec_t, count: c_int) count as usize }; - check_array_from_user(iov, count); + check_array(iov, count); let bufs_vec = { let mut bufs_vec = Vec::with_capacity(count); for iov_i in 0..count { @@ -194,7 +162,7 @@ fn do_readv(fd: c_int, iov: *mut iovec_t, count: c_int) count as usize }; - check_array_from_user(iov, count); + check_array(iov, count); let mut bufs_vec = { let mut bufs_vec = Vec::with_capacity(count); for iov_i in 0..count { @@ -274,7 +242,7 @@ fn do_brk(new_brk_addr: *const c_void) -> Result<*const c_void, Error> { fn do_wait4(pid: c_int, _exit_status: *mut c_int) -> Result { if _exit_status != 0 as *mut c_int { - check_mut_ptr_from_user(_exit_status)?; + check_mut_ptr(_exit_status)?; } let child_process_filter = match pid { @@ -310,7 +278,7 @@ fn do_wait4(pid: c_int, _exit_status: *mut c_int) -> Result { } fn do_pipe2(fds_u: *mut c_int, flags: c_int) -> Result<(), Error> { - check_mut_array_from_user(fds_u, 2)?; + check_mut_array(fds_u, 2)?; // TODO: how to deal with open flags??? let fds = fs::do_pipe2(flags as u32)?; unsafe { @@ -321,7 +289,7 @@ fn do_pipe2(fds_u: *mut c_int, flags: c_int) -> Result<(), Error> { } fn do_gettimeofday(tv_u: *mut timeval_t) -> Result<(), Error> { - check_mut_ptr_from_user(tv_u)?; + check_mut_ptr(tv_u)?; let tv = time::do_gettimeofday(); unsafe { *tv_u = tv; } Ok(()) diff --git a/src/libos/src/util/mem_util.rs b/src/libos/src/util/mem_util.rs new file mode 100644 index 00000000..60bfc2e4 --- /dev/null +++ b/src/libos/src/util/mem_util.rs @@ -0,0 +1,110 @@ +use super::*; +use std::ffi::{CStr, CString}; +use std::{ptr}; + +/// Memory utilities that deals with primitive types passed from user process +/// running inside enclave +pub mod from_user { + use super::*; + + /// Check the user pointer is within the readable memory range of the user process + pub fn check_ptr(user_ptr: *const T) -> Result<(), Error> { + Ok(()) + } + + /// Check the mutable user pointer is within the writable memory of the user process + pub fn check_mut_ptr(user_ptr: *mut T) -> Result<(), Error> { + Ok(()) + } + + /// Check the readonly array is within the readable memory of the user process + pub fn check_array(user_buf: *const T, count: usize) -> Result<(), Error> { + Ok(()) + } + + /// Check the mutable array is within the writable memory of the user process + pub fn check_mut_array(user_buf: *mut T, count: usize) -> Result<(), Error> { + Ok(()) + } + + /// Clone a C-string from the user process safely + pub fn clone_cstring_safely(out_ptr: *const c_char) + -> Result + { + check_ptr(out_ptr)?; + // TODO: using from_ptr directly is not safe + let cstr = unsafe { CStr::from_ptr(out_ptr) }; + let cstring = CString::from(cstr); + Ok(cstring) + } + + /// Clone a C-string array (const char*[]) from the user process safely + /// + /// This array must be ended with a NULL pointer. + pub fn clone_cstrings_safely(user_ptr: *const *const c_char) + -> Result, Error> + { + let mut cstrings = Vec::new(); + let mut user_ptr = user_ptr; + while user_ptr != ptr::null() { + let cstr_ptr = unsafe { *user_ptr }; + let cstring = clone_cstring_safely(cstr_ptr)?; + cstrings.push(cstring); + user_ptr = unsafe { user_ptr.offset(1) }; + } + Ok(cstrings) + } +} + +/// Memory utilities that deals with primitive types passed from outside the enclave +pub mod from_untrusted { + use super::*; + + /// Check the untrusted pointer is outside the enclave + pub fn check_ptr(out_ptr: *const T) -> Result<(), Error> { + Ok(()) + } + + /// Check the untrusted array is outside the enclave + pub fn check_array(out_ptr: *const T, count: usize) -> Result<(), Error> { + Ok(()) + } + + /// Clone a C-string from outside the enclave + pub fn clone_cstring_safely(out_ptr: *const c_char) + -> Result + { + check_ptr(out_ptr)?; + // TODO: using from_ptr directly is not safe + let cstr = unsafe { CStr::from_ptr(out_ptr) }; + let cstring = CString::from(cstr); + Ok(cstring) + } + + /// Clone a C-string array (const char*[]) from outside the enclave + /// + /// This array must be ended with a NULL pointer. + pub fn clone_cstrings_safely(out_ptr: *const *const c_char) + -> Result, Error> + { + let mut cstrings = Vec::new(); + if out_ptr == ptr::null() { return Ok(cstrings); } + + let mut out_ptr = out_ptr; + loop { + check_ptr(out_ptr); + let cstr_ptr = { + let cstr_ptr = unsafe { *out_ptr }; + if cstr_ptr == ptr::null() { break; } + check_ptr(cstr_ptr); + cstr_ptr + }; + let cstring = clone_cstring_safely(cstr_ptr)?; + cstrings.push(cstring); + + out_ptr = unsafe { out_ptr.offset(1) }; + } + Ok(cstrings) + } +} + diff --git a/src/libos/src/util/mod.rs b/src/libos/src/util/mod.rs index 018640b4..dc581bfa 100644 --- a/src/libos/src/util/mod.rs +++ b/src/libos/src/util/mod.rs @@ -1,8 +1,5 @@ use super::*; -pub use self::mpx_util::{*}; -pub use self::ring_buf::{RingBufReader, RingBufWriter}; -pub use self::ring_buf::with_fixed_capacity as new_ring_buf; - -mod mpx_util; -mod ring_buf; +pub mod mpx_util; +pub mod ring_buf; +pub mod mem_util; diff --git a/src/libos/src/util/ring_buf.rs b/src/libos/src/util/ring_buf.rs index 65be50d2..1a33c969 100644 --- a/src/libos/src/util/ring_buf.rs +++ b/src/libos/src/util/ring_buf.rs @@ -4,11 +4,19 @@ use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering}; use std::cmp::{min, max}; use std::{ptr}; -pub fn with_fixed_capacity(capacity: usize) -> (RingBufReader, RingBufWriter) { - let inner = Arc::new(RingBufInner::new(capacity)); - let reader = RingBufReader { inner: inner.clone() }; - let writer = RingBufWriter { inner: inner }; - (reader, writer) +#[derive(Debug)] +pub struct RingBuf { + pub reader: RingBufReader, + pub writer: RingBufWriter, +} + +impl RingBuf { + pub fn new(capacity: usize) -> RingBuf { + let inner = Arc::new(RingBufInner::new(capacity)); + let reader = RingBufReader { inner: inner.clone() }; + let writer = RingBufWriter { inner: inner }; + RingBuf { reader: reader, writer: writer } + } } #[derive(Debug)] diff --git a/src/pal/pal.c b/src/pal/pal.c index cfd660bb..91104f6a 100644 --- a/src/pal/pal.c +++ b/src/pal/pal.c @@ -214,9 +214,9 @@ int SGX_CDECL main(int argc, char *argv[]) uint32_t sealed_log_size = 1024; uint8_t sealed_log[1024] = {0}; - if (argc != 2) { - printf("ERROR: The expected number of arguments is 1, but given %d\n\n", argc - 1); - printf("Usage: pal \n"); + if (argc < 2) { + printf("ERROR: at least one argument must be provided\n\n"); + printf("Usage: pal ...\n"); return -1; } const char* executable_path = argv[1]; @@ -229,7 +229,7 @@ int SGX_CDECL main(int argc, char *argv[]) return -1; } - sgx_ret = libos_boot(global_eid, &status, executable_path); + sgx_ret = libos_boot(global_eid, &status, executable_path, &argv[2]); if(sgx_ret != SGX_SUCCESS) { print_error_message(sgx_ret); return status; diff --git a/test/Makefile b/test/Makefile index b6036e8e..93244c38 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,7 +1,7 @@ CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) PROJECT_DIR := $(realpath $(CUR_DIR)/../) -TEST_SUITES := empty hello_world malloc file getpid spawn pipe time +TEST_SUITES := empty argv hello_world malloc file getpid spawn pipe time BUILD_TEST_SUITES := $(TEST_SUITES:%=%) RUN_TEST_SUITES := $(TEST_SUITES:%=test-%) CLEAN_TEST_SUITES := $(TEST_SUITES:%=clean-%) diff --git a/test/argv/Makefile b/test/argv/Makefile new file mode 100644 index 00000000..90664f55 --- /dev/null +++ b/test/argv/Makefile @@ -0,0 +1,14 @@ +include ../test_common.mk + +ARGC := 4 +ARG1 := 1 +ARG2 := arg2 +ARG3 := this is a string with spaces + +EXTRA_C_FLAGS := \ + -DEXPECTED_ARGC=$(ARGC) \ + -DEXPECTED_ARG1="\"$(ARG1)\"" \ + -DEXPECTED_ARG2="\"$(ARG2)\"" \ + -DEXPECTED_ARG3="\"$(ARG3)\"" +EXTRA_LINK_FLAGS := +BIN_ARGS := "$(ARG1)" "$(ARG2)" "$(ARG3)" diff --git a/test/argv/main.c b/test/argv/main.c new file mode 100644 index 00000000..e372d2e4 --- /dev/null +++ b/test/argv/main.c @@ -0,0 +1,30 @@ +#include +#include + +// Expected arguments are given by Makefile throught macro ARGC, ARG1, ARG2 and +// ARG3 +const char* expected_argv[EXPECTED_ARGC] = { + "bin.encrypted", + EXPECTED_ARG1, + EXPECTED_ARG2, + EXPECTED_ARG3, +}; + +int main(int argc, char* argv[]) { + if (argc != EXPECTED_ARGC) { + printf("ERROR: expect %d arguments, but %d are given\n", EXPECTED_ARGC, argc); + return -1; + } + + for (int arg_i = 0; arg_i < argc; arg_i++) { + const char* actual_arg = argv[arg_i]; + const char* expected_arg = expected_argv[arg_i]; + if (strcmp(actual_arg, expected_arg) != 0) { + printf("ERROR: expect argument %d is %s, but given %s\n", + arg_i, expected_arg, actual_arg); + } + } + + printf("main()'s argc and argv are as expected\n"); + return 0; +} diff --git a/test/empty/Makefile b/test/empty/Makefile index b71a4d49..9e1b6dec 100644 --- a/test/empty/Makefile +++ b/test/empty/Makefile @@ -2,3 +2,4 @@ include ../test_common.mk EXTRA_C_FLAGS := EXTRA_LINK_FLAGS := +BIN_ARGS := diff --git a/test/file/Makefile b/test/file/Makefile index b71a4d49..9e1b6dec 100644 --- a/test/file/Makefile +++ b/test/file/Makefile @@ -2,3 +2,4 @@ include ../test_common.mk EXTRA_C_FLAGS := EXTRA_LINK_FLAGS := +BIN_ARGS := diff --git a/test/getpid/Makefile b/test/getpid/Makefile index b71a4d49..9e1b6dec 100644 --- a/test/getpid/Makefile +++ b/test/getpid/Makefile @@ -2,3 +2,4 @@ include ../test_common.mk EXTRA_C_FLAGS := EXTRA_LINK_FLAGS := +BIN_ARGS := diff --git a/test/hello_world/Makefile b/test/hello_world/Makefile index b71a4d49..9e1b6dec 100644 --- a/test/hello_world/Makefile +++ b/test/hello_world/Makefile @@ -2,3 +2,4 @@ include ../test_common.mk EXTRA_C_FLAGS := EXTRA_LINK_FLAGS := +BIN_ARGS := diff --git a/test/malloc/Makefile b/test/malloc/Makefile index b71a4d49..9e1b6dec 100644 --- a/test/malloc/Makefile +++ b/test/malloc/Makefile @@ -2,3 +2,4 @@ include ../test_common.mk EXTRA_C_FLAGS := EXTRA_LINK_FLAGS := +BIN_ARGS := diff --git a/test/pipe/Makefile b/test/pipe/Makefile index b71a4d49..9e1b6dec 100644 --- a/test/pipe/Makefile +++ b/test/pipe/Makefile @@ -2,3 +2,4 @@ include ../test_common.mk EXTRA_C_FLAGS := EXTRA_LINK_FLAGS := +BIN_ARGS := diff --git a/test/spawn/Makefile b/test/spawn/Makefile index b71a4d49..9e1b6dec 100644 --- a/test/spawn/Makefile +++ b/test/spawn/Makefile @@ -2,3 +2,4 @@ include ../test_common.mk EXTRA_C_FLAGS := EXTRA_LINK_FLAGS := +BIN_ARGS := diff --git a/test/test_common.mk b/test/test_common.mk index bcebc0b2..fadb3f7b 100644 --- a/test/test_common.mk +++ b/test/test_common.mk @@ -56,7 +56,7 @@ $(C_OBJS): %.o: %.c ############################################################################# test: $(BIN_ENC_NAME) - @cd ../ && RUST_BACKTRACE=1 ./pal $(CUR_DIR)/$(BIN_ENC_NAME) + @cd ../ && RUST_BACKTRACE=1 ./pal $(CUR_DIR)/$(BIN_ENC_NAME) $(BIN_ARGS) ############################################################################# # Misc diff --git a/test/time/Makefile b/test/time/Makefile index b71a4d49..9e1b6dec 100644 --- a/test/time/Makefile +++ b/test/time/Makefile @@ -2,3 +2,4 @@ include ../test_common.mk EXTRA_C_FLAGS := EXTRA_LINK_FLAGS := +BIN_ARGS :=