Handle exit status correctly
This commit is contained in:
parent
e5d3ab3cf9
commit
05e5efdb57
@ -49,10 +49,10 @@ pub extern "C" fn libos_boot(path_buf: *const i8) -> i32 {
|
||||
backtrace::__rust_begin_short_backtrace(||{
|
||||
match do_boot(&path_str) {
|
||||
Ok(()) => 0,
|
||||
Err(err) => err.errno.as_retval() /* Normal error */,
|
||||
Err(err) => EXIT_STATUS_INTERNAL_ERROR,
|
||||
}
|
||||
})
|
||||
}).unwrap_or(-1 /* Fatal error */)
|
||||
}).unwrap_or(EXIT_STATUS_INTERNAL_ERROR)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@ -61,13 +61,16 @@ pub extern "C" fn libos_run() -> i32 {
|
||||
panic::catch_unwind(||{
|
||||
backtrace::__rust_begin_short_backtrace(||{
|
||||
match do_run() {
|
||||
Ok(()) => 0,
|
||||
Err(err) => err.errno.as_retval() /* Normal error */,
|
||||
Ok(exit_status) => exit_status,
|
||||
Err(err) => EXIT_STATUS_INTERNAL_ERROR,
|
||||
}
|
||||
})
|
||||
}).unwrap_or(-1 /* Fatal 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> {
|
||||
@ -81,7 +84,7 @@ fn do_boot(path_str: &str) -> Result<(), Error> {
|
||||
}
|
||||
|
||||
// TODO: make sure do_run() cannot be called before do_boot()
|
||||
fn do_run() -> Result<(), Error> {
|
||||
process::run_task()?;
|
||||
Ok(())
|
||||
fn do_run() -> Result<i32, Error> {
|
||||
let exit_status = process::run_task()?;
|
||||
Ok(exit_status)
|
||||
}
|
||||
|
@ -11,21 +11,21 @@ pub fn do_getpid() -> pid_t {
|
||||
current_process.get_pid()
|
||||
}
|
||||
|
||||
pub fn do_exit(exit_code: i32) {
|
||||
pub fn do_exit(exit_status: i32) {
|
||||
let current_ref = get_current();
|
||||
let mut current_process = current_ref.lock().unwrap();
|
||||
current_process.exit(exit_code);
|
||||
current_process.exit(exit_status);
|
||||
}
|
||||
|
||||
pub fn do_wait4(child_pid: u32) -> Result<i32, Error> {
|
||||
let child_process = process_table::get(child_pid)
|
||||
.ok_or_else(|| (Errno::ECHILD, "Cannot find child process with the given PID"))?;
|
||||
|
||||
let mut exit_code = 0;
|
||||
let mut exit_status = 0;
|
||||
loop {
|
||||
let guard = child_process.lock().unwrap();
|
||||
if guard.get_status() == Status::ZOMBIE {
|
||||
exit_code = guard.get_exit_code();
|
||||
exit_status = guard.get_exit_status();
|
||||
break;
|
||||
}
|
||||
drop(guard);
|
||||
@ -34,7 +34,7 @@ pub fn do_wait4(child_pid: u32) -> Result<i32, Error> {
|
||||
let child_pid = child_process.lock().unwrap().get_pid();
|
||||
process_table::remove(child_pid);
|
||||
|
||||
Ok(exit_code)
|
||||
Ok(exit_status)
|
||||
}
|
||||
|
||||
mod task;
|
||||
|
@ -12,7 +12,7 @@ pub struct Process {
|
||||
status: Status,
|
||||
pid: pid_t,
|
||||
tgid: pid_t,
|
||||
exit_code: i32,
|
||||
exit_status: i32,
|
||||
exec_path: String,
|
||||
vm: ProcessVM,
|
||||
file_table: FileTable,
|
||||
@ -31,7 +31,7 @@ impl Process {
|
||||
pid: new_pid,
|
||||
tgid: new_pid,
|
||||
exec_path: exec_path.to_owned(),
|
||||
exit_code: 0,
|
||||
exit_status: 0,
|
||||
vm: vm,
|
||||
file_table: file_table,
|
||||
}));
|
||||
@ -43,15 +43,15 @@ impl Process {
|
||||
pub fn get_pid(&self) -> pid_t { self.pid }
|
||||
pub fn get_tgid(&self) -> pid_t { self.tgid }
|
||||
pub fn get_status(&self) -> Status { self.status }
|
||||
pub fn get_exit_code(&self) -> i32 { self.exit_code }
|
||||
pub fn get_exit_status(&self) -> i32 { self.exit_status }
|
||||
pub fn get_exec_path(&self) -> &str { &self.exec_path }
|
||||
pub fn get_vm(&self) -> &ProcessVM { &self.vm }
|
||||
pub fn get_vm_mut(&mut self) -> &mut ProcessVM { &mut self.vm }
|
||||
pub fn get_files(&self) -> &FileTable { &self.file_table }
|
||||
pub fn get_files_mut(&mut self) -> &mut FileTable { &mut self.file_table }
|
||||
|
||||
pub fn exit(&mut self, exit_code: i32) {
|
||||
self.exit_code = exit_code;
|
||||
pub fn exit(&mut self, exit_status: i32) {
|
||||
self.exit_status = exit_status;
|
||||
self.status = Status::ZOMBIE;
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ fn dequeue_task() -> Option<ProcessRef> {
|
||||
}
|
||||
|
||||
|
||||
pub fn run_task() -> Result<(), Error> {
|
||||
pub fn run_task() -> Result<i32, Error> {
|
||||
let new_process : ProcessRef = dequeue_task()
|
||||
.ok_or_else(|| (Errno::EAGAIN, "No new processes to run"))?;
|
||||
set_current(&new_process);
|
||||
@ -51,13 +51,18 @@ pub fn run_task() -> Result<(), Error> {
|
||||
do_run_task(task);
|
||||
}
|
||||
|
||||
let exit_status = {
|
||||
let mut process = new_process.lock().unwrap();
|
||||
process.get_exit_status()
|
||||
};
|
||||
|
||||
// Init process does not have any parent, so it has to release itself
|
||||
if pid == 1 {
|
||||
process_table::remove(1);
|
||||
}
|
||||
|
||||
reset_current();
|
||||
Ok(())
|
||||
Ok(exit_status)
|
||||
}
|
||||
|
||||
|
||||
|
@ -370,12 +370,12 @@ pub extern "C" fn occlum_spawn(
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn occlum_wait4(child_pid: c_int, _exit_code: *mut c_int,
|
||||
pub extern "C" fn occlum_wait4(child_pid: c_int, _exit_status: *mut c_int,
|
||||
options: c_int/*, rusage: *mut Rusage*/) -> c_int
|
||||
{
|
||||
match process::do_wait4(child_pid as u32) {
|
||||
Ok(exit_code) => unsafe {
|
||||
*_exit_code = exit_code;
|
||||
Ok(exit_status) => unsafe {
|
||||
*_exit_status = exit_status;
|
||||
0
|
||||
}
|
||||
Err(e) => {
|
||||
|
@ -225,7 +225,7 @@ int SGX_CDECL main(int argc, char *argv[])
|
||||
sgx_ret = libos_boot(global_eid, &status, executable_path);
|
||||
if(sgx_ret != SGX_SUCCESS) {
|
||||
print_error_message(sgx_ret);
|
||||
return -1;
|
||||
return status;
|
||||
}
|
||||
|
||||
status = wait_all_tasks();
|
||||
|
Loading…
Reference in New Issue
Block a user