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