From cf486f7d95a7092881885cb1be6b91e2aa5ccb09 Mon Sep 17 00:00:00 2001 From: zhanghuanhuan Date: Fri, 16 Jun 2023 13:57:21 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E6=9E=9A=E4=B8=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bash-5.1/builtins_rust/common/src/lib.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bash-5.1/builtins_rust/common/src/lib.rs b/bash-5.1/builtins_rust/common/src/lib.rs index e3e6bfd8..bd8eefea 100644 --- a/bash-5.1/builtins_rust/common/src/lib.rs +++ b/bash-5.1/builtins_rust/common/src/lib.rs @@ -519,3 +519,14 @@ macro_rules! J_JOBSTATE { (*$j).state } } + +//enum +#[repr(i8)] +#[derive(PartialEq)] +pub enum JOB_STATE { + JNONE = -1, + JRUNNING = 1, + JSTOPPED = 2, + JDEAD = 4, + JMIXED = 8 +} -- Gitee From cab8e2bd761df49150cb99912cb667a1168b402b Mon Sep 17 00:00:00 2001 From: zhanghuanhuan Date: Fri, 16 Jun 2023 14:02:36 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bash-5.1/builtins_rust/common/src/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bash-5.1/builtins_rust/common/src/lib.rs b/bash-5.1/builtins_rust/common/src/lib.rs index bd8eefea..131b671d 100644 --- a/bash-5.1/builtins_rust/common/src/lib.rs +++ b/bash-5.1/builtins_rust/common/src/lib.rs @@ -530,3 +530,10 @@ pub enum JOB_STATE { JDEAD = 4, JMIXED = 8 } + +//type +pub type sh_builtin_func_t = fn (*mut WordList)->i32; +pub type QSFUNC = unsafe extern "C" fn(*const c_void,*const c_void)->i32; +pub static EX_SUCCESS:i32 = 0; +pub static EX_USAGE:i32 = 258; +include!("./shell.rs"); -- Gitee From a48a79b35c499010d34b9daacf14ee1252d51e79 Mon Sep 17 00:00:00 2001 From: zhanghuanhuan Date: Fri, 16 Jun 2023 14:03:56 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20c=20=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bash-5.1/builtins_rust/common/src/lib.rs | 59 +++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/bash-5.1/builtins_rust/common/src/lib.rs b/bash-5.1/builtins_rust/common/src/lib.rs index 131b671d..e0ff7509 100644 --- a/bash-5.1/builtins_rust/common/src/lib.rs +++ b/bash-5.1/builtins_rust/common/src/lib.rs @@ -536,4 +536,61 @@ pub type sh_builtin_func_t = fn (*mut WordList)->i32; pub type QSFUNC = unsafe extern "C" fn(*const c_void,*const c_void)->i32; pub static EX_SUCCESS:i32 = 0; pub static EX_USAGE:i32 = 258; -include!("./shell.rs"); +include!("./shell.rs");//extern C + +extern "C"{ + static interactive_shell:i32; + static this_command_name:*mut c_char; + static mut current_builtin:*mut builtin; + static terminating_signal:c_int; + static interrupt_state:c_int; + static stdout:*mut FILE; + static mut posparam_count:i32; + static mut dollar_vars:[*mut c_char;10]; + static mut rest_of_args:*mut WordList; + static variable_context:i32; + static running_trap:i32; + static trap_saved_exit_value:i32; + static last_command_exit_value:i32; + static no_symbolic_links:i32; + // static bsah_getcwd_errstr:*const c_char; + static js:jobstats; + static jobs:*mut*mut JOB; + static assoc_expand_once:i32; + static shell_builtins:*mut builtin; + static mut num_shell_builtins:i32; + static posixly_correct:i32; + fn get_name_for_error()->*mut c_char; + fn executing_line_number()->i32; + fn top_level_cleanup(); + fn jump_to_top_level(value:i32); + fn internal_getopt(list:*mut WordList,opts:*mut c_char)->i32; + fn reset_internal_getopt(); + fn termsig_handler(sig:i32); + fn throw_to_top_level(); + fn fpurge(stream:*mut FILE) ->i32; + fn strvec_from_word_list(list:*mut WordList,alloc:i32,starting_index:i32,ip:*mut i32)->*mut *mut c_char; + fn xmalloc(n:size_t)->*mut c_void; + fn dispose_words(list:*mut WordList); + fn copy_word_list(list:*mut WordList)->*mut WordList; + fn list_length(list:*mut GENERIC_LIST)->i32; + fn invalidate_cached_quoted_dollar_at(); + fn set_builtin(list:*mut WordList)->i32; + fn legal_number(string:*mut c_char,result:*mut c_long)->i32; + fn return_builtin(list:*mut WordList)->i32; + fn getcwd(buf:*mut c_char,size:size_t)->*mut c_char; + fn internal_error(format:*const c_char,...); + fn strcasestr(s1:*const c_char,s2:*const c_char)->*mut c_char; + fn all_digits(string:*const c_char)->i32; + fn valid_array_reference(name:*const c_char,flags:i32)->i32; + fn bind_variable (name:* const c_char,value:* mut c_char,flags:i32)->* mut SHELL_VAR; + fn assign_array_element(name:*mut c_char,value:*mut c_char,flags:i32)->*mut SHELL_VAR; + fn find_variable(_:*const c_char)->*mut SHELL_VAR; + fn unbind_variable(name:*const c_char)->i32; + fn signal_name(sig:i32)->*mut c_char; + fn kill_builtin(list:*mut WordList)->i32; + fn decode_signal(string:*mut c_char,flags:i32)->i32; + fn builtin_help(); + + fn builtin_error(format:*const c_char,...); +} -- Gitee From 1f7ebc437fcc8bbeb24f6a6a94e8fe4e2692f2a5 Mon Sep 17 00:00:00 2001 From: zhanghuanhuan Date: Fri, 16 Jun 2023 14:05:23 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=87=BD=E6=95=B0=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bash-5.1/builtins_rust/common/src/lib.rs | 131 +++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/bash-5.1/builtins_rust/common/src/lib.rs b/bash-5.1/builtins_rust/common/src/lib.rs index e0ff7509..24bd1c0a 100644 --- a/bash-5.1/builtins_rust/common/src/lib.rs +++ b/bash-5.1/builtins_rust/common/src/lib.rs @@ -594,3 +594,134 @@ extern "C"{ fn builtin_error(format:*const c_char,...); } + +unsafe fn ISOPTION(s:* const c_char, c:c_char)->bool +{ + // return *s == '-' as c_char && *((s as usize + 1)as * mut c_char) == c && *((s as usize + 8)as * mut c_char) != 0; + return *s == '-' as c_char && *s.offset(1) == c && *s.offset(2) != 0; +} +/* Used by some builtins and the mainline code. */ +pub static mut last_shell_builtin:*mut sh_builtin_func_t = std::ptr::null_mut(); +pub static mut this_shell_builtin:*mut sh_builtin_func_t = std::ptr::null_mut(); + +/* **************************************************************** */ +/* */ +/* Error reporting, usage, and option processing */ +/* */ +/* **************************************************************** */ +/* This is a lot like report_error (), but it is for shell builtins + instead of shell control structures, and it won't ever exit the + shell. */ +#[no_mangle] +fn r_builitin_error_prolog(){ + let name:*mut c_char; + unsafe{ + name = get_name_for_error(); + eprint!("{}: ",CStr::from_ptr(name).to_str().unwrap()); + if interactive_shell == 0{ + eprint!("line {}: ",executing_line_number()) + } + if !this_command_name.is_null() && *this_command_name!=0{ + eprint!("{}:",CStr::from_ptr(name).to_str().unwrap()); + } + } +} +//builtin_error builtin_waring是可变参函数,先跳过 +/* Print a usage summary for the currently-executing builtin command. */ +#[no_mangle] +pub extern "C" fn r_builtin_usage(){ + unsafe{ + if !this_command_name.is_null() && *this_command_name != 0{ + eprint!("{}: usage: ",CStr::from_ptr(this_command_name).to_str().unwrap()); + eprintln!("{}",CStr::from_ptr((*current_builtin).short_doc).to_str().unwrap() ); + // stderr().flush(); + } + } + +} +/* Return if LIST is NULL else barf and jump to top_level. Used by some + builtins that do not accept arguments. */ +#[no_mangle] +pub extern "C" fn r_no_args(list:*mut WordList){ + unsafe{ + if !list.is_null(){ + let c_str = CString::new("too many arguments").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr); + top_level_cleanup(); + jump_to_top_level(DISCARD!()); + } + } +} +/* Check that no options were given to the currently-executing builtin, + and return 0 if there were options. */ +#[no_mangle] +pub extern "C" fn r_no_options(list:*mut WordList)->i32{ + let opt:i32; + unsafe{ + reset_internal_getopt(); + let c_str = CString::new("").unwrap(); + let c_ptr = c_str.as_ptr(); + opt = internal_getopt(list,c_ptr as *mut libc::c_char); + if opt != -1{ + if opt == GETOPT_HELP!(){ + builtin_help(); + return 2; + } + r_builtin_usage(); + return 1; + } + return 0; + } +} +#[no_mangle] +pub extern "C" fn r_sh_needarg(s:*mut c_char){ + unsafe{ + let c_str = CString::new("%s: option requires an argument").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr,s); + } +} +#[no_mangle] +pub extern "C" fn r_sh_neednumarg(s:*mut c_char){ + unsafe{ + let c_str = CString::new("%s: numeric argument requited").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr,s); + } +} +#[no_mangle] +pub extern "C" fn r_sh_notfound(s:*mut c_char){ + unsafe{ + let c_str = CString::new("%s: not found").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr,s); + } +} +/* Function called when one of the builtin commands detects an invalid + option. */ +#[no_mangle] +pub extern "C" fn r_sh_invalidopt(s:*mut c_char){ + unsafe{ + let c_str = CString::new("%s: invalid option").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr,s); + } +} +#[no_mangle] +pub extern "C" fn r_sh_invalidoptname(s:*mut c_char){ + unsafe{ + let c_str = CString::new("%s: invalid option name").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr,s); + } +} +#[no_mangle] +pub extern "C" fn r_sh_invalidid(s:*mut c_char){ + unsafe{ + let c_str = CString::new("`%s': not a valid identifier").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr,s); + } +} + -- Gitee From 6b928581e75b5433df520b5c6a281ab79085e7e0 Mon Sep 17 00:00:00 2001 From: zhanghuanhuan Date: Fri, 16 Jun 2023 14:07:37 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=87=BD=E6=95=B0=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bash-5.1/builtins_rust/common/src/lib.rs | 117 ++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) diff --git a/bash-5.1/builtins_rust/common/src/lib.rs b/bash-5.1/builtins_rust/common/src/lib.rs index 24bd1c0a..52947dda 100644 --- a/bash-5.1/builtins_rust/common/src/lib.rs +++ b/bash-5.1/builtins_rust/common/src/lib.rs @@ -723,5 +723,120 @@ pub extern "C" fn r_sh_invalidid(s:*mut c_char){ let c_ptr = c_str.as_ptr(); builtin_error(c_ptr,s); } +}#[no_mangle] +pub extern "C" fn r_sh_invalidnum(s:*mut c_char){ + unsafe{ + // let msg:*mut c_char; + let mut msg = String::new(); + let mut mag_ptr:*const c_char = std::ptr::null_mut(); + if *s == b'0' as libc::c_char && isdigit(*s.offset(1) as c_int) != 0{ + msg.push_str("invalid octal number"); + mag_ptr = msg.as_ptr() as *mut c_char; + } + else if *s == b'0' as libc::c_char && *s.offset(1) == b'x' as libc::c_char{ + msg.push_str("invalid hex number"); + mag_ptr = msg.as_ptr() as *mut c_char; + } + else { + msg.push_str("invalid number"); + mag_ptr = msg.as_ptr() as *mut c_char; + } + let c_str = CString::new("%s: %s").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr,s,mag_ptr); + } +} +#[no_mangle] +pub extern "C" fn r_sh_invalidsig(s:*mut c_char){ + unsafe{ + let c_str = CString::new("%s: invalid signal specification").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr,s); + } +} +#[no_mangle] +pub extern "C" fn r_sh_badpid(s:*mut c_char){ + unsafe{ + let c_str = CString::new("`%s': not a pid or valid job spec").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr,s); + } +} +#[no_mangle] +pub extern "C" fn r_sh_readonly(s:*mut c_char){ + unsafe{ + let c_str = CString::new("%s: readonly variable").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr,s); + } +} +#[no_mangle] +pub extern "C" fn r_sh_erange(s:*mut c_char,desc:*mut c_char){ + unsafe{ + if !s.is_null(){ + let c_str = CString::new("%s: %s out of range").unwrap(); + let c_ptr = c_str.as_ptr(); + if !desc.is_null(){ + builtin_error(c_ptr, s,desc); + } + else{ + let desc_str = CString::new("argument").unwrap(); + let desc_ptr = desc_str.as_ptr(); + builtin_error(c_ptr, s,desc_ptr); + } + } + else{ + let c_str = CString::new("%s out of range").unwrap(); + let c_ptr = c_str.as_ptr(); + let desc_str = CString::new("argument").unwrap(); + let desc_ptr = desc_str.as_ptr(); + builtin_error(c_ptr,desc_ptr) + } + } +} +#[no_mangle] +pub extern "C" fn r_sh_badjob(s:*mut c_char){ + unsafe{ + let c_str = CString::new("%s: no job control").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr,s); + } +} +#[no_mangle] +pub extern "C" fn r_sh_nojobs(s:*mut c_char){ + unsafe{ + if !s.is_null(){ + let c_str = CString::new("%s: no job control").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr,s); + } + else{ + let c_str = CString::new("no job control").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr); + } + } +} +#[no_mangle] +pub extern "C" fn r_sh_restricted(s:*mut c_char){ + unsafe{ + if !s.is_null(){ + let c_str = CString::new("%s: restricted").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr,s); + } + else{ + let c_str = CString::new("restricted").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr); + } + } +} +#[no_mangle] +pub extern "C" fn r_sh_notbuiltin(s:*mut c_char){ + unsafe{ + let c_str = CString::new("%s: not a shell builtin").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr,s); + } } - -- Gitee From 69adca1876c59c1742b40bdbd661a8a24c239f76 Mon Sep 17 00:00:00 2001 From: zhanghuanhuan Date: Fri, 16 Jun 2023 14:09:35 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=87=BD=E6=95=B0=203?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bash-5.1/builtins_rust/common/src/lib.rs | 245 +++++++++++++++++++++++ 1 file changed, 245 insertions(+) diff --git a/bash-5.1/builtins_rust/common/src/lib.rs b/bash-5.1/builtins_rust/common/src/lib.rs index 52947dda..f3edc2ed 100644 --- a/bash-5.1/builtins_rust/common/src/lib.rs +++ b/bash-5.1/builtins_rust/common/src/lib.rs @@ -840,3 +840,248 @@ pub extern "C" fn r_sh_notbuiltin(s:*mut c_char){ builtin_error(c_ptr,s); } } + +#[no_mangle] +pub extern "C" fn r_sh_wrerror(){ + unsafe{ + let c_str = CString::new("write error: %s").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr,strerror(*__errno_location())); + } +} +#[no_mangle] +pub extern "C" fn r_sh_ttyerror(set:i32){ + unsafe{ + if set != 0{ + let c_str = CString::new("error setting terminal attributes: %s").unwrap(); + let c_str_ptr = c_str.as_ptr(); + builtin_error(c_str_ptr,strerror(*__errno_location())); + } + else{ + let c_str = CString::new("error getting terminal attributes: %s").unwrap(); + let c_str_ptr = c_str.as_ptr(); + builtin_error(c_str_ptr,strerror(*__errno_location())); + } + } +} +#[no_mangle] +pub extern "C" fn r_sh_chkwrite(s:i32)->i32{ + unsafe{ + QUIT!(); + fflush(stdout); + QUIT!(); + if ferror(stdout) != 0{ + r_sh_wrerror(); + fpurge(stdout); + clearerr(stdout); + return EXECUTION_FAILURE!(); + } + return s; + } +} +/* **************************************************************** */ +/* */ +/* Shell positional parameter manipulation */ +/* */ +/* **************************************************************** */ +/* Convert a WordList into a C-style argv. Return the number of elements + in the list in *IP, if IP is non-null. A convenience function for + loadable builtins; also used by `test'. */ +#[no_mangle] +pub extern "C" fn r_make_builtin_argv(list:*mut WordList,ip:*mut i32)->*mut *mut c_char{ + let argv:*mut *mut c_char; + unsafe{ + argv = strvec_from_word_list(list,0,1,ip); + *argv.offset(0) = this_command_name; + return argv; + } +} +/* Remember LIST in $1 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is + non-zero, then discard whatever the existing arguments are, else + only discard the ones that are to be replaced. Set POSPARAM_COUNT + to the number of args assigned (length of LIST). */ +#[no_mangle] +pub extern "C" fn r_remember_args(mut list:*mut WordList,destructive:i32){ + let mut i:i32; + + unsafe{ + posparam_count = 0; + i = 1; + while i<10{ + if (destructive !=0 || list != std::ptr::null_mut()) && *dollar_vars.as_ptr().offset(i as isize) != std::ptr::null_mut(){ + free(*dollar_vars.as_ptr().offset(i as isize) as *mut c_void); + *dollar_vars.as_mut_ptr().offset(i as isize) = std::ptr::null_mut(); + } + if !list.is_null(){ + posparam_count = i; + *dollar_vars.as_mut_ptr().offset(posparam_count as isize) = r_savestring((*(*list).word).word); + list = (*list).next; + } + i += 1; + } + /* If arguments remain, assign them to REST_OF_ARGS. + Note that copy_word_list (NULL) returns NULL, and + that dispose_words (NULL) does nothing. */ + if destructive !=0 || !list.is_null(){ + dispose_words(rest_of_args); + rest_of_args = copy_word_list(list); + posparam_count += list_length(list as *mut GENERIC_LIST);//there is may be problems + } + if destructive != 0{ + r_set_dollar_vars_changed(); + } + invalidate_cached_quoted_dollar_at(); + } +} + +#[no_mangle] +pub extern "C" fn r_shift_args(mut times:i32){ + let mut temp:*mut WordList; + // let mut count:i32; + unsafe{ + if times <= 0{ + return; + } + times -= 1; //可能存在问题 + while times > 0 { + if *dollar_vars.as_ptr().offset(1) != std::ptr::null_mut(){ + free(*dollar_vars.as_ptr().offset(1) as *mut c_void); + } + for count in 1..9{ + *dollar_vars.as_mut_ptr().offset(count) = *dollar_vars.as_ptr().offset(count+1) + } + if !rest_of_args.is_null(){ + temp = rest_of_args; + *dollar_vars.as_mut_ptr().offset(9) = r_savestring((*(*temp).word).word); + rest_of_args = (*rest_of_args).next; + (*temp).next = std::ptr::null_mut(); + dispose_words(temp); + } + else{ + *dollar_vars.as_mut_ptr().offset(9) = std::ptr::null_mut(); + } + posparam_count -= 1; + times -= 1; + } + } +} +#[no_mangle] +pub extern "C" fn r_number_of_args()->i32{ + unsafe{ + return posparam_count; + } +} +static mut changed_dollar_vars:i32 = 0; +/* Have the dollar variables been reset to new values since we last + checked? */ +#[no_mangle] +pub extern "C" fn r_dollar_vars_changed()->i32{ + unsafe{ + return changed_dollar_vars; + } +} +#[no_mangle] +pub extern "C" fn r_set_dollar_vars_unchanged(){ + unsafe{ + changed_dollar_vars = 0; + } +} +#[no_mangle] +pub extern "C" fn r_set_dollar_vars_changed(){ + unsafe{ + if variable_context != 0{ + changed_dollar_vars |= ARGS_FUNC!(); + } + else if this_shell_builtin == set_builtin as *mut sh_builtin_func_t{ //there may be problems + changed_dollar_vars |= ARGS_SETBLTIN!(); + } + else{ + changed_dollar_vars |= ARGS_INVOC!(); + } + } +} +/* **************************************************************** */ +/* */ +/* Validating numeric input and arguments */ +/* */ +/* **************************************************************** */ +/* Read a numeric arg for this_command_name, the name of the shell builtin + that wants it. LIST is the word list that the arg is to come from. + Accept only the numeric argument; report an error if other arguments + follow. If FATAL is 1, call throw_to_top_level, which exits the + shell; if it's 2, call jump_to_top_level (DISCARD), which aborts the + current command; if FATAL is 0, return an indication of an invalid + number by setting *NUMOK == 0 and return -1. */ +#[no_mangle] +pub extern "C" fn r_get_numeric_arg(mut list:*mut WordList,fatal:i32,count:*mut intmax_t)->i32{ + let arg:*mut c_char; + unsafe{ + if !count.is_null(){ + *count = 1; + } + if !list.is_null() && !(*list).word.is_null() && ISOPTION((*(*list).word).word,b'-' as libc::c_char){ + list = (*list).next; + } + if !list.is_null(){ + arg = (*(*list).word).word; + if arg.is_null() || legal_number(arg,count) == 0{ + if !(*(*list).word).word.is_null(){ + r_sh_neednumarg((*(*list).word).word); + } + else { + r_sh_neednumarg(String::from("`'").as_ptr() as *mut libc::c_char); + } + + if fatal == 0{ + return 0; + } + else if fatal == 1{ /* fatal == 1; abort */ + throw_to_top_level(); + } + else{ /* fatal == 2; discard current command */ + top_level_cleanup(); + jump_to_top_level(DISCARD!()); + } + } + r_no_args((*list).next); + } + return 1; + } +} +/* Get an eight-bit status value from LIST */ +#[no_mangle] +pub extern "C" fn r_get_exitstat(mut list:*mut WordList)->i32{ + let status:i32; + let mut sval:intmax_t = 0; + let arg:*mut c_char; + unsafe{ + if !list.is_null() && !(*list).word.is_null() && ISOPTION((*(*list).word).word,b'-' as libc::c_char){ + list = (*list).next; + } + if list.is_null(){ + /* If we're not running the DEBUG trap, the return builtin, when not + given any arguments, uses the value of $? before the trap ran. If + given an argument, return uses it. This means that the trap can't + change $?. The DEBUG trap gets to change $?, though, since that is + part of its reason for existing, and because the extended debug mode + does things with the return value. */ + if this_shell_builtin == return_builtin as *mut sh_builtin_func_t && running_trap > 0 && running_trap != DEBUG_TRAP!()+1{ + return trap_saved_exit_value; + } + return last_command_exit_value; + } + arg = (*(*list).word).word; + if arg.is_null() || legal_number(arg,&mut sval) == 0{ + if !(*(*list).word).word.is_null(){ + r_sh_neednumarg((*(*list).word).word); + } + else { + r_sh_neednumarg(String::from("`'").as_ptr() as *mut libc::c_char); + } + return EX_BADUSAGE!(); + } + r_no_args((*list).next); + status = (sval & 255) as i32; + return status; + } +} -- Gitee