From 27b4c55e224394dd949b5aa9d543078af1b94c99 Mon Sep 17 00:00:00 2001 From: zhanghuanhuan Date: Wed, 9 Aug 2023 16:36:17 +0800 Subject: [PATCH] =?UTF-8?q?=201=20=E6=B7=BB=E5=8A=A0getsopts=20=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=20rust=20=E6=BA=90=E7=A0=81=202=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E4=BA=8C=E7=BA=A7=E6=8C=87=E9=92=88=E5=81=8F=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bash-5.1/builtins_rust/cd/src/lib.rs | 416 +++++++++--------------- bash-5.1/builtins_rust/fc/src/lib.rs | 4 +- bash-5.1/builtins_rust/fg_bg/src/lib.rs | 162 +++++---- bash-5.1/builtins_rust/jobs/src/lib.rs | 256 +++++++-------- record.txt | 1 + 5 files changed, 359 insertions(+), 480 deletions(-) diff --git a/bash-5.1/builtins_rust/cd/src/lib.rs b/bash-5.1/builtins_rust/cd/src/lib.rs index bc17200..bb10f8c 100644 --- a/bash-5.1/builtins_rust/cd/src/lib.rs +++ b/bash-5.1/builtins_rust/cd/src/lib.rs @@ -29,7 +29,7 @@ pub enum JOB_STATE { #[repr(u8)] enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select, cm_connection, cm_function_def, cm_until, cm_group, - cm_arith, cm_cond, cm_arith_for, cm_subshell, cm_coproc + cm_arith, cm_cond, cm_arith_for, cm_subshell, cm_coproc } #[repr(u8)] @@ -56,8 +56,8 @@ pub struct PROCESS { #[repr(C)] #[derive(Copy,Clone)] pub union REDIRECTEE { - dest:libc::c_int, /* Place to redirect REDIRECTOR to, or ... */ - filename:* mut WORD_DESC /* filename to redirect to. */ + dest:libc::c_int, + filename:* mut WORD_DESC } #[repr(C)] @@ -71,7 +71,6 @@ pub union REDIRECT { here_doc_eof:*mut c_char /* The word that appeared in < {1} } + #[macro_export] macro_rules! EX_USAGE { () => {258} } + #[macro_export] macro_rules! EXECUTION_SUCCESS { () => {0} } -#[macro_export] -macro_rules! BLOCK_SIGNAL { - ($sig:expr, $nvar:expr, $ovar:expr) => { - $nvar.unwrap().clear(); - $nvar.unwrap().add($sig); - $nvar.unwrap().clear(); - nix::sys::signal::sigprocmask(nix::sys::signal::SigmaskHow::SIG_BLOCK, $nvar, $ovar); - } -} - -#[macro_export] -macro_rules! UNBLOCK_SIGNAL { - ($ovar:expr) => { - nix::sys::signal::sigprocmask(nix::sys::signal::SigmaskHow::SIG_SETMASK, $ovar, None) - } -} -#[macro_export] -macro_rules! UNBLOCK_CHILD { - ($ovar:expr) => { - UNBLOCK_SIGNAL!($ovar); - } -} - -#[macro_export] -macro_rules! BLOCK_CHILD { - ($nvar:expr,$ovar:expr) => { - BLOCK_SIGNAL!(nix::sys::signal::SIGCHLD, $nvar, $ovar); - } -} #[macro_export] macro_rules! DUP_JOB { () => {-2} } -#[macro_export] -macro_rules! get_job_by_jid { - ($ind:expr) => { - (*(((jobs as i32) + $ind*8 ) as *mut*mut JOB) as *mut JOB) - } -} - -#[macro_export] -macro_rules! J_JOBCONTROL { - () => {0x04} -} - -#[macro_export] -macro_rules! IS_JOBCONTROL { - ($j:expr) => { - ((*get_job_by_jid!($j)).flags & J_JOBCONTROL!()) != 0 - } -} - -#[macro_export] -macro_rules! INVALID_JOB { - ($j:expr) => { - $j <0 || $j >= js.j_jobslots || get_job_by_jid !($j) == std::ptr::null_mut() - } -} - -#[macro_export] -macro_rules! ISHELP { - ($s:expr) => { - libc::strcmp($s as *const c_char,CString::new("--help").unwrap().as_ptr()) - } -} - -#[macro_export] -macro_rules! CHECK_HELPOPT { - ($l:expr) => { - if $l !=std::ptr::null_mut() && (*$l).word !=std::ptr::null_mut() && ISHELP!((*(*$l).word).word) == 0 - { - builtin_help (); - return EX_USAGE!(); - } - } -} - #[macro_export] macro_rules! readonly_p { ($var:expr) => { (*$var).attributes & 0x0000002 } } + #[macro_export] macro_rules! exported_p { ($var:expr) => { @@ -411,24 +298,28 @@ macro_rules! LCD_PRINTPATH { 0x004 } } + #[macro_export] macro_rules! LCD_FREEDIRNAME { () => { 0x008 } } + #[macro_export] macro_rules! MP_DOTILDE { () => { 0x01 } } + #[macro_export] macro_rules! PATH_CHECKDOTDOT { () => { 0x0001 } } + #[macro_export] macro_rules! PATH_CHECKEXISTS { () => { @@ -443,8 +334,8 @@ macro_rules! errno { } } -extern "C" { - fn builtin_error(err:*const c_char,...); +extern "C" { + fn builtin_error(err:*const c_char,...); static mut loptend:*mut WORD_LIST; @@ -455,14 +346,14 @@ extern "C" { fn get_working_directory (for_whom:* mut c_char)->* mut c_char; fn sh_physpath (path:*mut c_char, flags:i32)->* mut c_char; fn sh_chkwrite (s:i32)->i32; - fn get_string_value (var_name:*const c_char)->* mut c_char; + fn get_string_value (var_name:*const c_char)->* mut c_char; static mut restricted:i32; fn sh_restricted (s:*mut c_char); static no_symbolic_links:i32; - fn reset_internal_getopt(); - fn internal_getopt (list:*mut WORD_LIST , opts:*mut c_char)->i32; + fn reset_internal_getopt(); + fn internal_getopt (list:*mut WORD_LIST , opts:*mut c_char)->i32; fn builtin_usage(); static cdable_vars:i32; static interactive:i32; @@ -474,32 +365,30 @@ extern "C" { fn dirspell (dirname:* mut c_char)->* mut c_char; fn printable_filename (fnc:* mut c_char, flags:i32)->* mut c_char; - static posixly_correct:i32; + static posixly_correct:i32; fn same_file (path1:*const c_char, path2:*const c_char, stp1:*mut libc::stat, stp2:*mut libc::stat)->i32; fn make_absolute (str1:*const c_char, dot_path:*const c_char)->* mut c_char; fn sh_canonpath (path:* mut c_char, flags:i32)->* mut c_char; - fn set_working_directory (path:* mut c_char); - - - + fn set_working_directory (path:* mut c_char); } + pub static mut xattrfd:i32=-1; pub static mut xattrflag:i32=0; pub static mut verbatim_pwd:i32=0; pub static mut eflag:i32=0; + /* How to bring a job into the foreground. */ #[no_mangle] pub extern "C" fn r_setpwd (dirname:* mut c_char)->i32 { let old_anm:i32; let tvar:* mut SHELL_VAR; - unsafe { + unsafe { old_anm = array_needs_making; let c_str_pwd = CString::new("PWD").unwrap(); if dirname ==std::ptr::null_mut() { - tvar=bind_variable (c_str_pwd.as_ptr(), CString::new("").unwrap().as_ptr() as * mut c_char, 0); - + tvar=bind_variable (c_str_pwd.as_ptr(), CString::new("").unwrap().as_ptr() as * mut c_char, 0); } else { tvar = bind_variable (c_str_pwd.as_ptr(), dirname , 0); } @@ -510,11 +399,10 @@ pub extern "C" fn r_setpwd (dirname:* mut c_char)->i32 if tvar !=std::ptr::null_mut() && old_anm == 0 && array_needs_making !=0 && exported_p !(tvar) !=0 { if dirname ==std::ptr::null_mut() { - update_export_env_inplace (c_str_pwd.as_ptr() as * mut c_char, 4, CString::new("").unwrap().as_ptr() as * mut c_char); - + update_export_env_inplace (c_str_pwd.as_ptr() as * mut c_char, 4, CString::new("").unwrap().as_ptr() as * mut c_char); } else { update_export_env_inplace (c_str_pwd.as_ptr() as * mut c_char, 4, dirname); - } + } array_needs_making = 0; } return EXECUTION_SUCCESS!(); @@ -522,7 +410,7 @@ pub extern "C" fn r_setpwd (dirname:* mut c_char)->i32 } #[no_mangle] -pub extern "C" fn r_bindpwd (no_symlinks:i32)->i32{ +pub extern "C" fn r_bindpwd (no_symlinks:i32)->i32 { let mut dirname:*mut c_char; let pwdvar:*mut c_char; let old_anm:i32; @@ -531,20 +419,18 @@ pub extern "C" fn r_bindpwd (no_symlinks:i32)->i32{ let tvar:* mut SHELL_VAR; unsafe { r = sh_chkwrite (EXECUTION_SUCCESS!()); - - -if the_current_working_directory !=std::ptr::null_mut() { - if no_symlinks !=0{ - dirname=sh_physpath (the_current_working_directory, 0); - }else { - dirname =the_current_working_directory + if the_current_working_directory !=std::ptr::null_mut() { + if no_symlinks !=0{ + dirname=sh_physpath (the_current_working_directory, 0); + }else { + dirname =the_current_working_directory; + } + } else { + let c_str_cd = CString::new("cd").unwrap(); + dirname=get_working_directory(c_str_cd.as_ptr() as * mut c_char); } -} else { - let c_str_cd = CString::new("cd").unwrap(); - dirname=get_working_directory(c_str_cd.as_ptr() as * mut c_char); -} -/* If canonicalization fails, reset dirname to the_current_working_directory */ + /* If canonicalization fails, reset dirname to the_current_working_directory */ canon_failed = 0; if dirname == std::ptr::null_mut() { canon_failed = 1; @@ -558,22 +444,22 @@ if the_current_working_directory !=std::ptr::null_mut() { tvar = bind_variable (CString::new("OLDPWD").unwrap().as_ptr(), pwdvar, 0); if tvar !=std::ptr::null_mut() && readonly_p! (tvar) !=0{ r = EXECUTION_FAILURE!(); - } + } if old_anm == 0 && array_needs_making !=0 && exported_p! (tvar) !=0 { update_export_env_inplace (CString::new("OLDPWD").unwrap().as_ptr() as * mut c_char, 7, pwdvar); array_needs_making = 0; - } + } - if r_setpwd (dirname) == EXECUTION_FAILURE!(){ + if r_setpwd (dirname) == EXECUTION_FAILURE!() { r = EXECUTION_FAILURE!(); } - - if canon_failed !=0 && eflag !=0{ + + if canon_failed !=0 && eflag !=0 { r = EXECUTION_FAILURE!(); - } + } - if dirname !=std::ptr::null_mut() && dirname != the_current_working_directory{ + if dirname !=std::ptr::null_mut() && dirname != the_current_working_directory { libc::free(dirname as * mut libc::c_void); } return r; @@ -583,7 +469,7 @@ if the_current_working_directory !=std::ptr::null_mut() { /* Call get_working_directory to reset the value of the_current_working_directory () */ #[no_mangle] -pub extern "C" fn r_resetpwd (caller:*mut c_char)->*mut c_char{ +pub extern "C" fn r_resetpwd (caller:*mut c_char)->*mut c_char { let tdir:*mut c_char; unsafe { libc::free(the_current_working_directory as * mut libc::c_void); @@ -594,19 +480,19 @@ pub extern "C" fn r_resetpwd (caller:*mut c_char)->*mut c_char{ } #[no_mangle] -pub extern "C" fn r_cdxattr (dir: *mut c_char, ndirp:*mut c_char)->i32{ +pub extern "C" fn r_cdxattr (dir: *mut c_char, ndirp:*mut c_char)->i32 { return -1; } #[no_mangle] -pub extern "C" fn r_resetxattr (){ +pub extern "C" fn r_resetxattr () { unsafe { xattrfd = -1; /* not strictly necessary */ - } + } } #[no_mangle] -pub extern "C" fn r_cd_builtin (list:*mut WORD_LIST)->i32{ +pub extern "C" fn r_cd_builtin (list:*mut WORD_LIST)->i32 { let mut dirname:*mut c_char=std::ptr::null_mut(); let cdpath:*mut c_char; let mut path:*mut c_char; @@ -625,24 +511,24 @@ pub extern "C" fn r_cd_builtin (list:*mut WORD_LIST)->i32{ eflag = 0; no_symlinks = no_symbolic_links; xattrflag = 0; - reset_internal_getopt (); - let c_str_elp = CString::new("eLP").unwrap(); // from a &str, creates a new allocation + reset_internal_getopt (); + let c_str_elp = CString::new("eLP").unwrap(); // from a &str, creates a new allocation opt = internal_getopt (list, c_str_elp.as_ptr() as * mut c_char); - while opt != -1{ + while opt != -1 { let optu8:u8= opt as u8; let optChar:char=char::from(optu8); - match optChar{ - 'P'=>{no_symlinks = 1;} - 'L'=>{no_symlinks = 0;} - 'e'=>{eflag = 1;} - _=>{ - builtin_usage (); - return EX_USAGE!(); - } + match optChar { + 'P'=>{no_symlinks = 1;} + 'L'=>{no_symlinks = 0;} + 'e'=>{eflag = 1;} + _=>{ + builtin_usage (); + return EX_USAGE!(); + } } opt =internal_getopt (list, c_str_elp.as_ptr() as * mut c_char); } - + if cdable_vars != 0 { lflag=LCD_DOVARS!(); } else { @@ -657,13 +543,13 @@ pub extern "C" fn r_cd_builtin (list:*mut WORD_LIST)->i32{ if eflag !=0 && no_symlinks == 0{ eflag = 0; - } + } if loptend == std::ptr::null_mut() { /* `cd' without arguments is equivalent to `cd $HOME' */ dirname = get_string_value (CString::new("HOME").unwrap().as_ptr()); - if dirname == std::ptr::null_mut(){ + if dirname == std::ptr::null_mut() { builtin_error (CString::new("HOME not set").unwrap().as_ptr()); return EXECUTION_FAILURE!(); } @@ -671,22 +557,20 @@ pub extern "C" fn r_cd_builtin (list:*mut WORD_LIST)->i32{ }else if (*loptend).next != std::ptr::null_mut() { builtin_error (CString::new("too many arguments").unwrap().as_ptr()); return EXECUTION_FAILURE!(); - }else if char::from((*(*(*loptend).word).word) as u8) == '-' && char::from(*((((*(*loptend).word).word) as u8 +1) as *mut c_char) as u8) == '\0' { + }else if char::from((*(*(*loptend).word).word) as u8) == '-' && char::from(*((((*(*loptend).word).word) as usize +4) as *mut c_char) as u8) == '\0' { /* This is `cd -', equivalent to `cd $OLDPWD' */ dirname = get_string_value (CString::new("OLDPWD").unwrap().as_ptr()); - if dirname == std::ptr::null_mut() - { + if dirname == std::ptr::null_mut() { builtin_error (CString::new("OLDPWD not set").unwrap().as_ptr()); return EXECUTION_FAILURE!(); } lflag = LCD_PRINTPATH!(); /* According to SUSv3 */ - - }else if absolute_pathname ((*(*loptend).word).word) !=0{ + } else if absolute_pathname ((*(*loptend).word).word) !=0 { dirname = (*(*loptend).word).word; - }else if privileged_mode == 0 { + } else if privileged_mode == 0 { cdpath = get_string_value (CString::new("CDPATH").unwrap().as_ptr() ); - if cdpath !=std::ptr::null_mut(){ + if cdpath !=std::ptr::null_mut() { dirname = (*(*loptend).word).word; /* Find directory in $CDPATH. */ path_index = 0; @@ -697,22 +581,23 @@ pub extern "C" fn r_cd_builtin (list:*mut WORD_LIST)->i32{ temp = sh_makepath (path, dirname, MP_DOTILDE!()); libc::free (path as * mut c_void); - if r_change_to_directory (temp, no_symlinks, xattrflag) !=0{ + if r_change_to_directory (temp, no_symlinks, xattrflag) !=0 { /* POSIX.2 says that if a nonempty directory from CDPATH is used to find the directory to change to, the new directory name is echoed to stdout, whether or not the shell is interactive. */ if opt !=0 { - if no_symlinks !=0{ + if no_symlinks !=0 { path=temp; } else { path=the_current_working_directory; } + if path !=std::ptr::null_mut() { - println!("{:?}",path); + libc::printf(CString::new("%s\n").unwrap().as_ptr() as * const c_char,path); } } - + libc::free (temp as * mut c_void); return r_bindpwd (no_symlinks); @@ -726,25 +611,24 @@ pub extern "C" fn r_cd_builtin (list:*mut WORD_LIST)->i32{ } else{ dirname = (*(*loptend).word).word; } - + /* When we get here, DIRNAME is the directory to change to. If we chdir successfully, just return. */ if 0 != r_change_to_directory (dirname, no_symlinks, xattrflag) { - if (lflag & LCD_PRINTPATH!()) !=0{ - println!("{:?}", dirname); - } - return r_bindpwd (no_symlinks); + if (lflag & LCD_PRINTPATH!()) !=0 { + libc::printf(CString::new("%s\n").unwrap().as_ptr() as * const c_char,dirname); } + return r_bindpwd (no_symlinks); + } /* If the user requests it, then perhaps this is the name of a shell variable, whose value contains the directory to change to. */ if (lflag & LCD_DOVARS!()) !=0 { temp = get_string_value (dirname); - if temp != std::ptr::null_mut() && r_change_to_directory (temp, no_symlinks, xattrflag) !=0 - { - println!("{:?}", temp); + if temp != std::ptr::null_mut() && r_change_to_directory (temp, no_symlinks, xattrflag) !=0 { + libc::printf(CString::new("%s\n").unwrap().as_ptr() as * const c_char,temp); return r_bindpwd (no_symlinks); } } @@ -761,24 +645,21 @@ pub extern "C" fn r_cd_builtin (list:*mut WORD_LIST)->i32{ } else { libc::free (temp as * mut c_void); } - } - e =errno!(); + e =errno!(); temp = printable_filename (dirname, 0); builtin_error (CString::new("%s: %s").unwrap().as_ptr(), temp, libc::strerror (e)); - if temp != dirname{ + + if temp != dirname { libc::free (temp as * mut c_void); - } - + } return EXECUTION_FAILURE!(); - } - } #[no_mangle] -pub extern "C" fn r_pwd_builtin (list:* mut WORD_LIST)->i32{ +pub extern "C" fn r_pwd_builtin (list:* mut WORD_LIST)->i32 { let mut directory:* mut c_char; let mut opt:i32; let mut pflag:i32; @@ -786,9 +667,9 @@ pub extern "C" fn r_pwd_builtin (list:* mut WORD_LIST)->i32{ verbatim_pwd = no_symbolic_links; pflag = 0; reset_internal_getopt (); - let c_str_lp = CString::new("LP").unwrap(); // from a &str, creates a new allocation + let c_str_lp = CString::new("LP").unwrap(); // from a &str, creates a new allocation opt = internal_getopt (list, c_str_lp.as_ptr() as * mut c_char); - while opt != -1{ + while opt != -1 { let optu8:u8= opt as u8; let optChar:char=char::from(optu8); match optChar{ @@ -797,28 +678,25 @@ pub extern "C" fn r_pwd_builtin (list:* mut WORD_LIST)->i32{ 'L'=>{verbatim_pwd = 0;} _=>{builtin_usage (); return EX_USAGE!(); - } + } } opt = internal_getopt (list, c_str_lp.as_ptr() as * mut c_char); } - if the_current_working_directory != std::ptr::null_mut() { - if verbatim_pwd != 0 { - directory=sh_physpath (the_current_working_directory, 0); - } else { - directory=the_current_working_directory; - } - } else { - directory=get_working_directory(CString::new("pwd").unwrap().as_ptr() as * mut c_char); - } - - + if the_current_working_directory != std::ptr::null_mut() { + if verbatim_pwd != 0 { + directory=sh_physpath (the_current_working_directory, 0); + } else { + directory=the_current_working_directory; + } + } else { + directory=get_working_directory(CString::new("pwd").unwrap().as_ptr() as * mut c_char); + } /* Try again using getcwd() if canonicalization fails (for instance, if the file system has changed state underneath bash). */ if (the_current_working_directory != std::ptr::null_mut() && directory == std::ptr::null_mut()) || - (posixly_correct !=0 && same_file (CString::new(".").unwrap().as_ptr(), the_current_working_directory, std::ptr::null_mut() , std::ptr::null_mut()) == 0) - { - if directory !=std::ptr::null_mut() && directory != the_current_working_directory{ + (posixly_correct !=0 && same_file (CString::new(".").unwrap().as_ptr(), the_current_working_directory, std::ptr::null_mut() , std::ptr::null_mut()) == 0) { + if directory !=std::ptr::null_mut() && directory != the_current_working_directory { libc::free (directory as * mut c_void); } directory = r_resetpwd (CString::new("pwd").unwrap().as_ptr() as * mut c_char); @@ -826,20 +704,19 @@ pub extern "C" fn r_pwd_builtin (list:* mut WORD_LIST)->i32{ if directory != std::ptr::null_mut() { opt = EXECUTION_SUCCESS!(); - println!("{:?}",directory); + libc::printf(CString::new("%s\n").unwrap().as_ptr() as * const c_char,directory); /* This is dumb but posix-mandated. */ - if posixly_correct !=0 && pflag !=0{ + if posixly_correct !=0 && pflag !=0 { opt = r_setpwd (directory); } - if directory != the_current_working_directory{ + if directory != the_current_working_directory { libc::free (directory as * mut c_void); } return sh_chkwrite (opt); - } else{ + } else { return EXECUTION_FAILURE!(); - } - + } } } @@ -848,9 +725,8 @@ pub extern "C" fn r_pwd_builtin (list:* mut WORD_LIST)->i32{ the_current_working_directory either set to NULL (in which case getcwd() will eventually be called), or set to a string corresponding to the working directory. Return 1 on success, 0 on failure. */ - #[no_mangle] -pub extern "C" fn r_change_to_directory (newdir:* mut c_char, nolinks:i32, xattr:i32)->i32{ +pub extern "C" fn r_change_to_directory (newdir:* mut c_char, nolinks:i32, xattr:i32)->i32 { unsafe { let mut t:*mut c_char; let mut tdir:*mut c_char; @@ -872,7 +748,7 @@ pub extern "C" fn r_change_to_directory (newdir:* mut c_char, nolinks:i32, xattr /* TDIR is either the canonicalized absolute pathname of NEWDIR (nolinks == 0) or the absolute physical pathname of NEWDIR (nolinks != 0). */ - if nolinks !=0{ + if nolinks !=0 { tdir=sh_physpath (t, 0); } else { tdir=sh_canonpath (t, PATH_CHECKDOTDOT!()|PATH_CHECKEXISTS!()); @@ -885,7 +761,7 @@ pub extern "C" fn r_change_to_directory (newdir:* mut c_char, nolinks:i32, xattr canon_failed = 0; if tdir !=std::ptr::null_mut() && *tdir !=0 { libc::free (t as * mut c_void); - } else { + } else { libc::free (tdir as * mut c_void); tdir = t; canon_failed = 1; @@ -894,10 +770,8 @@ pub extern "C" fn r_change_to_directory (newdir:* mut c_char, nolinks:i32, xattr /* In POSIX mode, if we're resolving symlinks logically and sh_canonpath returns NULL (because it checks the path, it will return NULL if the resolved path doesn't exist), fail immediately. */ - if posixly_correct !=0 && nolinks == 0 && canon_failed !=0 && (errno!() != libc::ENAMETOOLONG || ndlen > libc::PATH_MAX) { - - if errno!() != libc::ENOENT && errno!() != libc::ENAMETOOLONG{ + if errno!() != libc::ENOENT && errno!() != libc::ENAMETOOLONG { errno!() = libc::ENOTDIR; } libc::free (tdir as * mut c_void); @@ -907,31 +781,31 @@ pub extern "C" fn r_change_to_directory (newdir:* mut c_char, nolinks:i32, xattr { if nolinks !=0 { r = libc::chdir (newdir); - } else{ + } else { r = libc::chdir (tdir); } - - if r >= 0{ + + if r >= 0 { r_resetxattr (); } - + } /* If the chdir succeeds, update the_current_working_directory. */ - if r == 0{ + if r == 0 { /* If canonicalization failed, but the chdir succeeded, reset the shell's idea of the_current_working_directory. */ if canon_failed !=0 { t = r_resetpwd (CString::new("cd").unwrap().as_ptr() as * mut c_char); - if t == std::ptr::null_mut(){ - set_working_directory (tdir); - } else{ - libc::free (t as * mut c_void); - } - } else { + if t == std::ptr::null_mut(){ set_working_directory (tdir); + } else { + libc::free (t as * mut c_void); } - + } else { + set_working_directory (tdir); + } + libc::free (tdir as * mut c_void); return 1; } @@ -939,7 +813,7 @@ pub extern "C" fn r_change_to_directory (newdir:* mut c_char, nolinks:i32, xattr /* We failed to change to the appropriate directory name. If we tried what the user passed (nolinks != 0), punt now. */ if nolinks !=0 { - libc::free (tdir as * mut c_void); + libc::free (tdir as * mut c_void); return 0; } @@ -951,18 +825,28 @@ pub extern "C" fn r_change_to_directory (newdir:* mut c_char, nolinks:i32, xattr POSIX requires that we just fail here, so we do in posix mode. */ if posixly_correct == 0 && libc::chdir (newdir) == 0 { t = r_resetpwd (CString::new("cd").unwrap().as_ptr() as * mut c_char); - if t == std::ptr::null_mut(){ + if t == std::ptr::null_mut() { set_working_directory (tdir); - } else{ + } else { libc::free (t as * mut c_void); } r = 1; - } else { - errno!()= err; - r = 0; - } + } else { + errno!()= err; + r = 0; + } - libc::free (tdir as * mut c_void); + libc::free (tdir as * mut c_void); return r; } +} + +#[no_mangle] +pub extern "C" fn cmd_name() ->*const u8 { + return b"cd" as *const u8; +} + +#[no_mangle] +pub extern "C" fn run(list : *mut WORD_LIST)->i32 { + return r_cd_builtin(list); } \ No newline at end of file diff --git a/bash-5.1/builtins_rust/fc/src/lib.rs b/bash-5.1/builtins_rust/fc/src/lib.rs index 3bba296..069c032 100644 --- a/bash-5.1/builtins_rust/fc/src/lib.rs +++ b/bash-5.1/builtins_rust/fc/src/lib.rs @@ -488,14 +488,14 @@ unsafe fn QUIT () } unsafe fn DIGIT ( c: c_char)->bool { - char::from(c as u8) >= '0' && char::from(c as u8) <= '9' + char::from(c as u8) >= '0' && char::from(c as u8) <= '9' } unsafe fn STREQN ( a:* const c_char, b:* const c_char, n:i32)->bool { if n==0 { return true; } else { - return *a == *b && libc::strncmp(a, b, n as libc::size_t) == 0 + return *((a as usize +4) as * const c_char) ==*((b as usize +4) as * const c_char) && libc::strncmp(a, b, n as libc::size_t) == 0 } } diff --git a/bash-5.1/builtins_rust/fg_bg/src/lib.rs b/bash-5.1/builtins_rust/fg_bg/src/lib.rs index 56c9c81..689f42d 100644 --- a/bash-5.1/builtins_rust/fg_bg/src/lib.rs +++ b/bash-5.1/builtins_rust/fg_bg/src/lib.rs @@ -29,7 +29,7 @@ pub enum JOB_STATE { #[repr(u8)] enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select, cm_connection, cm_function_def, cm_until, cm_group, - cm_arith, cm_cond, cm_arith_for, cm_subshell, cm_coproc + cm_arith, cm_cond, cm_arith_for, cm_subshell, cm_coproc } #[repr(u8)] @@ -71,7 +71,6 @@ pub union REDIRECT { here_doc_eof:*mut c_char /* The word that appeared in < {1} } + #[macro_export] macro_rules! EX_USAGE { () => {258} } + #[macro_export] macro_rules! EXECUTION_SUCCESS { () => {0} } + #[macro_export] macro_rules! BLOCK_SIGNAL { - ($sig:expr, $nvar:expr, $ovar:expr) => { + ($sig:expr, $nvar:expr, $ovar:expr) => { $nvar.unwrap().clear(); $nvar.unwrap().add($sig); $nvar.unwrap().clear(); - nix::sys::signal::sigprocmask(nix::sys::signal::SigmaskHow::SIG_BLOCK, $nvar, $ovar); + nix::sys::signal::sigprocmask(nix::sys::signal::SigmaskHow::SIG_BLOCK, $nvar, $ovar); } } #[macro_export] macro_rules! UNBLOCK_SIGNAL { ($ovar:expr) => { - nix::sys::signal::sigprocmask(nix::sys::signal::SigmaskHow::SIG_SETMASK, $ovar, None) + nix::sys::signal::sigprocmask(nix::sys::signal::SigmaskHow::SIG_SETMASK, $ovar, None) } } + #[macro_export] macro_rules! UNBLOCK_CHILD { ($ovar:expr) => { - UNBLOCK_SIGNAL!($ovar); + UNBLOCK_SIGNAL!($ovar); } } #[macro_export] macro_rules! BLOCK_CHILD { ($nvar:expr,$ovar:expr) => { - BLOCK_SIGNAL!(nix::sys::signal::SIGCHLD, $nvar, $ovar); + BLOCK_SIGNAL!(nix::sys::signal::SIGCHLD, $nvar, $ovar); } } @@ -321,7 +310,7 @@ macro_rules! DUP_JOB { #[macro_export] macro_rules! get_job_by_jid { ($ind:expr) => { - (*(((jobs as i32) + $ind*8 ) as *mut*mut JOB) as *mut JOB) + (*(((jobs as usize) + ($ind*8) as usize ) as *mut*mut JOB) as *mut JOB) } } @@ -340,25 +329,24 @@ macro_rules! IS_JOBCONTROL { #[macro_export] macro_rules! INVALID_JOB { ($j:expr) => { - $j <0 || $j >= js.j_jobslots || get_job_by_jid !($j) == std::ptr::null_mut() + $j <0 || $j >= js.j_jobslots || get_job_by_jid !($j) == std::ptr::null_mut() } } #[macro_export] macro_rules! ISHELP { - ($s:expr) => { - libc::strcmp($s as *const c_char,CString::new("--help").unwrap().as_ptr()) + ($s:expr) => { + libc::strcmp($s as *const c_char,CString::new("--help").unwrap().as_ptr()) } } #[macro_export] macro_rules! CHECK_HELPOPT { ($l:expr) => { - if $l !=std::ptr::null_mut() && (*$l).word !=std::ptr::null_mut() && ISHELP!((*(*$l).word).word) == 0 - { - builtin_help (); - return EX_USAGE!(); - } + if $l !=std::ptr::null_mut() && (*$l).word !=std::ptr::null_mut() && ISHELP!((*(*$l).word).word) == 0 { + builtin_help (); + return EX_USAGE!(); + } } } @@ -380,12 +368,12 @@ extern "C" { /* How to bring a job into the foreground. */ #[no_mangle] -pub extern "C" fn r_fg_builtin (list:*mut WORD_LIST)->i32{ +pub extern "C" fn r_fg_builtin (list:*mut WORD_LIST)->i32 { let fg_bit:i32; unsafe { CHECK_HELPOPT! (list); - if job_control == 0 { + if job_control == 0 { sh_nojobs (0 as *mut c_char); return EXECUTION_FAILURE!(); } @@ -397,23 +385,22 @@ pub extern "C" fn r_fg_builtin (list:*mut WORD_LIST)->i32{ /* If the last arg on the line is '&', then start this job in the background. Else, fg the job. */ - if loptend == std::ptr::null_mut(){ + if loptend == std::ptr::null_mut() { return r_fg_bg (loptend, 1); - }else { + } else { let mut t:WORD_LIST=*loptend; - while t.next !=std::ptr::null_mut(){ + while t.next !=std::ptr::null_mut() { t=*(t.next); } let cstr:&std::ffi::CStr=std::ffi::CStr::from_ptr((*(t.word)).word ); let mut isfg:bool=char::from( cstr.to_bytes()[0] ) == '&'; isfg =isfg && char::from( cstr.to_bytes()[1]) == '\0'; isfg = isfg ==false; - if isfg{ + if isfg { fg_bit=1; - }else { + } else { fg_bit=0; - } - + } return r_fg_bg (loptend, fg_bit); } } @@ -421,7 +408,7 @@ pub extern "C" fn r_fg_builtin (list:*mut WORD_LIST)->i32{ /* How to put a job into the background. */ #[no_mangle] -pub extern "C" fn r_bg_builtin (list:*mut WORD_LIST)->i32{ +pub extern "C" fn r_bg_builtin (list:*mut WORD_LIST)->i32 { let mut r:i32; unsafe { CHECK_HELPOPT !(list); @@ -439,23 +426,22 @@ pub extern "C" fn r_bg_builtin (list:*mut WORD_LIST)->i32{ on the first member (if any) of that list. */ r = EXECUTION_SUCCESS!(); - if r_fg_bg(loptend,0) == EXECUTION_FAILURE!(){ + if r_fg_bg(loptend,0) == EXECUTION_FAILURE!() { r = EXECUTION_FAILURE!(); } if loptend !=std::ptr::null_mut() { - let mut t:WORD_LIST=*loptend; + let mut t:WORD_LIST=*loptend; while t.next !=std::ptr::null_mut() { - if r_fg_bg (&mut t, 0) == EXECUTION_FAILURE!(){ + if r_fg_bg (&mut t, 0) == EXECUTION_FAILURE!() { r = EXECUTION_FAILURE!(); - } + } t = *(t.next); } return r; } else { return r; - } - + } } } @@ -471,58 +457,64 @@ pub extern "C" fn r_fg_bg (list:*mut WORD_LIST, foreground:i32)->i32{ let j:*mut JOB; unsafe { - - BLOCK_CHILD !(Some(&mut set), Some(&mut oset)); + BLOCK_CHILD !(Some(&mut set), Some(&mut oset)); job = get_job_spec (list); - if INVALID_JOB !(job){ - if job != DUP_JOB!(){ - if list != std::ptr::null_mut() { - sh_badjob ( (*(*list).word).word ); - }else { - let mut c_str_current = CString::new("current").unwrap(); // from a &str, creates a new allocation - sh_badjob (c_str_current.as_ptr() as * mut c_char); - } + if INVALID_JOB !(job) { + if job != DUP_JOB!() { + if list != std::ptr::null_mut() { + sh_badjob ( (*(*list).word).word ); + } else { + let mut c_str_current = CString::new("current").unwrap(); // from a &str, creates a new allocation + sh_badjob (c_str_current.as_ptr() as * mut c_char); } - - UNBLOCK_CHILD !(Some(&oset)); - return EXECUTION_FAILURE!(); } + UNBLOCK_CHILD !(Some(&oset)); + return EXECUTION_FAILURE!(); + } + j = get_job_by_jid !(job); /* Or if j->pgrp == shell_pgrp. */ - if ! IS_JOBCONTROL !(job) { + if ! IS_JOBCONTROL !(job) { let jobNum:i32=job + 1; builtin_error ( String::from("job ").add(&jobNum.to_string()).add(&String::from("started without job control").to_string()).as_ptr() as * const c_char); UNBLOCK_CHILD !(Some(&oset)); return EXECUTION_FAILURE!(); - } + } if foreground == 0 { old_async_pid = i32::from(last_asynchronous_pid); last_asynchronous_pid = i32::from((*j).pgrp); /* As per Posix.2 5.4.2 */ - } + } status = start_job (job, foreground); - if status >= 0{ + if status >= 0 { /* win: */ UNBLOCK_CHILD !(Some(&oset)); if foreground !=0 { return status; - }else { + } else { return EXECUTION_SUCCESS!(); } - } - else - { - if foreground == 0{ + } else { + if foreground == 0 { last_asynchronous_pid = i32::from(old_async_pid); } - + UNBLOCK_CHILD !(Some(&oset)); return EXECUTION_FAILURE!(); } } } +#[no_mangle] +pub extern "C" fn cmd_name() ->*const u8 { + return b"fg" as *const u8; +} + +#[no_mangle] +pub extern "C" fn run(list : *mut WORD_LIST)->i32 { + return r_fg_builtin(list); +} \ No newline at end of file diff --git a/bash-5.1/builtins_rust/jobs/src/lib.rs b/bash-5.1/builtins_rust/jobs/src/lib.rs index fc30276..9456b58 100644 --- a/bash-5.1/builtins_rust/jobs/src/lib.rs +++ b/bash-5.1/builtins_rust/jobs/src/lib.rs @@ -31,6 +31,7 @@ enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select, cm_connection, cm_function_def, cm_until, cm_group, cm_arith, cm_cond, cm_arith_for, cm_subshell, cm_coproc } + #[repr(u8)] #[derive(Copy,Clone)] enum r_instruction { @@ -41,7 +42,8 @@ enum r_instruction { r_duplicating_input_word, r_duplicating_output_word, r_move_input, r_move_output, r_move_input_word, r_move_output_word, r_append_err_and_out - } +} + #[repr(C)] pub struct PROCESS { next: *mut PROCESS, @@ -69,7 +71,6 @@ pub union REDIRECT { here_doc_eof:*mut c_char /* The word that appeared in < {3} } + #[macro_export] macro_rules! EXECUTION_FAILURE { () => {1} } + #[macro_export] macro_rules! JSTATE_RUNNING { () => {0x1} } + #[macro_export] macro_rules! JSTATE_STOPPED { () => {0x2} } + #[macro_export] macro_rules! EX_USAGE { () => {258} } + #[macro_export] macro_rules! EXECUTION_SUCCESS { () => {0} } + #[macro_export] macro_rules! BLOCK_SIGNAL { - ($sig:expr, $nvar:expr, $ovar:expr) => { + ($sig:expr, $nvar:expr, $ovar:expr) => { $nvar.unwrap().clear(); $nvar.unwrap().add($sig); $nvar.unwrap().clear(); - nix::sys::signal::sigprocmask(nix::sys::signal::SigmaskHow::SIG_BLOCK, $nvar, $ovar); + nix::sys::signal::sigprocmask(nix::sys::signal::SigmaskHow::SIG_BLOCK, $nvar, $ovar); } } @@ -317,17 +322,18 @@ macro_rules! UNBLOCK_SIGNAL { nix::sys::signal::sigprocmask(nix::sys::signal::SigmaskHow::SIG_SETMASK, $ovar, None) } } + #[macro_export] macro_rules! UNBLOCK_CHILD { ($ovar:expr) => { - UNBLOCK_SIGNAL!($ovar); + UNBLOCK_SIGNAL!($ovar); } } #[macro_export] macro_rules! BLOCK_CHILD { ($nvar:expr,$ovar:expr) => { - BLOCK_SIGNAL!(nix::sys::signal::SIGCHLD, $nvar, $ovar); + BLOCK_SIGNAL!(nix::sys::signal::SIGCHLD, $nvar, $ovar); } } @@ -340,6 +346,7 @@ macro_rules! NO_JOB { macro_rules! DUP_JOB { () => {-2} } + #[macro_export] macro_rules! CMD_INHIBIT_EXPANSION {/* Do not expand the command words. */ () => {0x20} @@ -348,14 +355,14 @@ macro_rules! CMD_INHIBIT_EXPANSION {/* Do not expand the command words. */ #[macro_export] macro_rules! get_job_by_jid { ($ind:expr) => { - (*(((jobs as i32) + $ind*8 ) as *mut*mut JOB) as *mut JOB) + (*((jobs as usize + ($ind*8) as usize ) as *mut*mut JOB) as *mut JOB) } } #[macro_export] macro_rules! INVALID_JOB { ($j:expr) => { - $j <0 || $j >= js.j_jobslots || get_job_by_jid !($j) == std::ptr::null_mut() + $j <0 || $j >= js.j_jobslots || get_job_by_jid !($j) == std::ptr::null_mut() } } @@ -365,15 +372,14 @@ extern "C" { fn internal_getopt (list:*mut WORD_LIST , opts:*mut c_char)->i32; fn builtin_error(err:*const c_char,...); fn builtin_usage(); - static mut loptend:*mut WORD_LIST; + static mut loptend:*mut WORD_LIST; fn list_all_jobs(form:i32); fn list_stopped_jobs(form:i32); - fn list_one_job (jjob:*mut JOB, format:i32, ignore:i32, job_index:i32); + fn list_one_job (jjob:*mut JOB, format:i32, ignore:i32, job_index:i32); fn get_job_spec (list:*mut WORD_LIST)->i32; fn sh_badjob (str:*mut c_char); static jobs:*mut*mut JOB; - fn discard_unwind_frame (str: * mut c_char); - + fn discard_unwind_frame (str: * mut c_char); fn begin_unwind_frame (str: * mut c_char); fn execute_command (command:* mut COMMAND)->i32; fn dispose_command (command:* mut COMMAND); @@ -388,34 +394,32 @@ extern "C" { fn nohup_all_jobs (running_only:i32); fn delete_all_jobs(running_only:i32); } + #[no_mangle] pub extern "C" fn r_execute_list_with_replacements (list:*mut WORD_LIST)->i32{ - println!("r_execute_list_with_replacements"); + //println!("r_execute_list_with_replacements"); unsafe{ - let mut l:WORD_LIST=*list; + let mut l:*mut WORD_LIST=list; let mut job:i32; let result:i32; let command:*mut COMMAND; - /* First do the replacement of job specifications with pids. */ - - while l.next !=std::ptr::null_mut() { - let lchar:char=char::from((*(*l.word).word) as u8); + /* First do the replacement of job specifications with pids. */ + while l !=std::ptr::null_mut() { + let lchar:char=char::from((*(*(*l).word).word) as u8); if lchar== '%' /* we have a winner */ { - job = get_job_spec (&mut l); - + job = get_job_spec ( l); /* A bad job spec is not really a job spec! Pass it through. */ if INVALID_JOB!(job){ continue; } - libc::free((*l.word).word as * mut libc::c_void); - (*(*l.word).word) = (*get_job_by_jid! (job)).pgrp as i8; - } - l=*(l.next); - } - - + libc::free((*(*l).word).word as * mut libc::c_void); + (*(*(*l).word).word) = (*get_job_by_jid! (job)).pgrp as i8; + } + l=(*l).next; + } + let mut c_str_jobs_builtin = CString::new("jobs_builtin").unwrap(); /* Next make a new simple command and execute it. */ begin_unwind_frame (c_str_jobs_builtin.as_ptr() as * mut c_char); @@ -429,15 +433,14 @@ extern "C" { add_unwind_protect(dispose_command, command); result = execute_command (command); dispose_command (command); - discard_unwind_frame (c_str_jobs_builtin.as_ptr() as * mut c_char); return result; } } #[no_mangle] -pub extern "C" fn r_jobs_builtin(list:*mut WORD_LIST)->i32{ - println!("r_jobs_builtin"); +pub extern "C" fn r_jobs_builtin(list:*mut WORD_LIST)->i32 { + //println!("r_jobs_builtin"); let mut form:i32; let mut execute:i32=0; let mut state:i32; @@ -452,43 +455,40 @@ pub extern "C" fn r_jobs_builtin(list:*mut WORD_LIST)->i32{ state = JSTATE_ANY!(); unsafe { - reset_internal_getopt(); - - let mut c_str_lpnxrs = CString::new("lpnxrs").unwrap(); // from a &str, creates a new allocation - - opt = internal_getopt (list, c_str_lpnxrs.as_ptr() as * mut c_char); - while opt != -1{ - let optu8:u8= opt as u8; - let optChar:char=char::from(optu8); - match optChar{ - 'l'=>{form = JLIST_LONG!();} - 'p'=>{form = JLIST_PID_ONLY!();} - 'n'=>{form = JLIST_CHANGED_ONLY!();} - 'x'=>{ - if form != JLIST_STANDARD!() { - let mut c_str_err = CString::new("no other options allowed with `-x'").unwrap(); // from a &str, creates a new allocation - builtin_error (c_str_err.as_ptr()); - return EXECUTION_FAILURE!(); - } - execute+=1; + reset_internal_getopt(); + + let mut c_str_lpnxrs = CString::new("lpnxrs").unwrap(); // from a &str, creates a new allocation + + opt = internal_getopt (list, c_str_lpnxrs.as_ptr() as * mut c_char); + while opt != -1 { + let optu8:u8= opt as u8; + let optChar:char=char::from(optu8); + match optChar{ + 'l'=>{form = JLIST_LONG!();} + 'p'=>{form = JLIST_PID_ONLY!();} + 'n'=>{form = JLIST_CHANGED_ONLY!();} + 'x'=>{ + if form != JLIST_STANDARD!() { + let mut c_str_err = CString::new("no other options allowed with `-x'").unwrap(); // from a &str, creates a new allocation + builtin_error (c_str_err.as_ptr()); + return EXECUTION_FAILURE!(); } - 'r'=>{state = JSTATE_RUNNING!();} - 's'=>{state = JSTATE_STOPPED!();} - - _=>{ - builtin_usage (); - return EX_USAGE!(); + execute+=1; } - - } - opt = internal_getopt (list, c_str_lpnxrs.as_ptr() as * mut c_char); + 'r'=>{state = JSTATE_RUNNING!();} + 's'=>{state = JSTATE_STOPPED!();} + _=>{ + builtin_usage (); + return EX_USAGE!(); + } } + opt = internal_getopt (list, c_str_lpnxrs.as_ptr() as * mut c_char); + } - - if execute != 0 { + if execute != 0 { return r_execute_list_with_replacements (loptend); - } - + } + if loptend ==std::ptr::null_mut() { if state == JSTATE_ANY!() { list_all_jobs (form); @@ -499,16 +499,16 @@ pub extern "C" fn r_jobs_builtin(list:*mut WORD_LIST)->i32{ } return EXECUTION_SUCCESS!(); } - + let mut loptendt=*loptend; while loptendt.next !=std::ptr::null_mut() { BLOCK_CHILD !(Some(&mut set), Some(&mut oset)); job = get_job_spec (&mut loptendt); if (job == NO_JOB!()) || jobs == std::ptr::null_mut() || get_job_by_jid !(job) == std::ptr::null_mut() { - sh_badjob ((*loptendt.word).word); + sh_badjob ((*loptendt.word).word); any_failed+=1; - } else if (job != DUP_JOB!()){ + } else if (job != DUP_JOB!()) { list_one_job (0 as * mut JOB, form, 0, job); } @@ -517,13 +517,14 @@ pub extern "C" fn r_jobs_builtin(list:*mut WORD_LIST)->i32{ } if any_failed !=0 { return EXECUTION_FAILURE!(); - }else { + } else { return EXECUTION_SUCCESS!(); } } } + #[no_mangle] -pub extern "C" fn r_disown_builtin (list:* mut WORD_LIST)->libc::c_int{ +pub extern "C" fn r_disown_builtin (list:* mut WORD_LIST)->libc::c_int { let opt:i32; let mut job:i32=0; let mut retval:i32; @@ -534,63 +535,58 @@ pub extern "C" fn r_disown_builtin (list:* mut WORD_LIST)->libc::c_int{ let mut set:nix::sys::signal::SigSet=nix::sys::signal::SigSet::empty(); let mut oset:nix::sys::signal::SigSet =nix::sys::signal::SigSet::empty(); let mut pid_value:c_long=0; - println!("r_disown_builtin"); + //println!("r_disown_builtin"); unsafe { reset_internal_getopt (); let mut c_str_ahr = CString::new("ahr").unwrap(); // from a &str, creates a new allocation - opt = internal_getopt (list, c_str_ahr.as_ptr() as * mut c_char); - while opt != -1{ + while opt != -1 { let optu8:u8= opt as u8; let optChar:char=char::from(optu8); match optChar{ - 'a'=>{all_jobs = 1;} - 'h'=>{nohup_only = 1;} - 'r'=>{running_jobs = 1;} - _=>{ - builtin_usage (); - return EX_USAGE!(); - } - + 'a'=>{all_jobs = 1;} + 'h'=>{nohup_only = 1;} + 'r'=>{running_jobs = 1;} + _=>{ + builtin_usage (); + return EX_USAGE!(); + } } - } - + } + retval = EXECUTION_SUCCESS!(); /* `disown -a' or `disown -r' */ if loptend == std::ptr::null_mut() && (all_jobs !=0 || running_jobs != 0) { if nohup_only!=0{ nohup_all_jobs (running_jobs); - } else{ + } else { delete_all_jobs (running_jobs); } - - return EXECUTION_SUCCESS!(); - } + return EXECUTION_SUCCESS!(); + } - BLOCK_CHILD !(Some(&mut set), Some(&mut oset)); - if (loptend !=std::ptr::null_mut() && legal_number ((*(*loptend).word).word, &mut pid_value) !=0 && pid_value == pid_value) { - job=get_job_by_pid ( pid_value as i32, 0, 0 as *mut*mut PROCESS); - }else { - get_job_spec (loptend); - - } - if job == NO_JOB!() || jobs !=std::ptr::null_mut() || INVALID_JOB!(job){ - if loptend !=std::ptr::null_mut() { + BLOCK_CHILD !(Some(&mut set), Some(&mut oset)); + if (loptend !=std::ptr::null_mut() && legal_number ((*(*loptend).word).word, &mut pid_value) !=0 && pid_value == pid_value) { + job=get_job_by_pid ( pid_value as i32, 0, 0 as *mut*mut PROCESS); + }else { + get_job_spec (loptend); + } + if job == NO_JOB!() || jobs !=std::ptr::null_mut() || INVALID_JOB!(job) { + if loptend !=std::ptr::null_mut() { sh_badjob ((*(*loptend).word).word); - }else { + } else { sh_badjob (CString::new("current").unwrap().as_ptr() as * mut c_char); - } - retval = EXECUTION_FAILURE!(); - } else if nohup_only !=0{ + } + retval = EXECUTION_FAILURE!(); + } else if nohup_only !=0{ nohup_job (job); } else { delete_job (job, 1); } - - UNBLOCK_CHILD !(Some(&oset)); - - + + UNBLOCK_CHILD !(Some(&oset)); + if loptend != std::ptr::null_mut() { let mut loptendt=*loptend; while loptendt.next !=std::ptr::null_mut() { @@ -598,24 +594,30 @@ pub extern "C" fn r_disown_builtin (list:* mut WORD_LIST)->libc::c_int{ BLOCK_CHILD !(Some(&mut set), Some(&mut oset)); if legal_number ((*loptendt.word).word, &mut pid_value) !=0 && pid_value == pid_value { job=get_job_by_pid ( pid_value as i32, 0, 0 as *mut*mut PROCESS); - }else { + } else { get_job_spec (&mut loptendt); - } - if job == NO_JOB!() || jobs !=std::ptr::null_mut() || INVALID_JOB!(job){ - - sh_badjob ((*loptendt.word).word); - + if job == NO_JOB!() || jobs !=std::ptr::null_mut() || INVALID_JOB!(job) { + sh_badjob ((*loptendt.word).word); retval = EXECUTION_FAILURE!(); } else if nohup_only !=0{ nohup_job (job); } else { delete_job (job, 1); } - UNBLOCK_CHILD !(Some(&oset)); } } return retval; } +} + +#[no_mangle] +pub extern "C" fn cmd_name() ->*const u8 { + return b"jobs" as *const u8; +} + +#[no_mangle] +pub extern "C" fn run(list : *mut WORD_LIST)->i32 { + return r_jobs_builtin(list); } \ No newline at end of file diff --git a/record.txt b/record.txt index 32107ab..f039df0 100644 --- a/record.txt +++ b/record.txt @@ -11,3 +11,4 @@ 10 11 12 +13 -- Gitee