From d8c9803c2d0cfb4c6df069c45f25802efe447110 Mon Sep 17 00:00:00 2001 From: zhanghuanhuan Date: Wed, 9 Aug 2023 16:36:12 +0800 Subject: [PATCH] =?UTF-8?q?=20=E6=B7=BB=E5=8A=A0cd=20rust=20=E6=BA=90?= =?UTF-8?q?=E7=A0=81,=E5=B9=B6=E4=BC=98=E5=8C=96=E6=8C=87=E9=92=88?= =?UTF-8?q?=E5=88=A4=E7=A9=BA=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bash-5.1/Cargo.toml | 4 +- bash-5.1/builtins_rust/cd/src/lib.rs | 416 +++++++++++++++--------- bash-5.1/builtins_rust/fg_bg/src/lib.rs | 14 +- bash-5.1/builtins_rust/jobs/src/lib.rs | 24 +- bash-5.1/execute_cmd.c | 3 +- bash-5.1/rsbuiltins.h | 2 + bash-5.1/src/lib.rs | 39 ++- record.txt | 1 + 8 files changed, 331 insertions(+), 172 deletions(-) diff --git a/bash-5.1/Cargo.toml b/bash-5.1/Cargo.toml index 48dca7e..6e02f0a 100644 --- a/bash-5.1/Cargo.toml +++ b/bash-5.1/Cargo.toml @@ -8,9 +8,11 @@ crate-type = ["cdylib"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [workspace] -members = ["builtins/command1", "builtins/command2"] +members = ["builtins_rust/read", "builtins/command1", "builtins/command2", "builtins_rust/common"] [dependencies] +libc = "0.2" command1 = {path = "./builtins/command1"} command2 = {path = "./builtins/command2"} read = {path = "./builtins_rust/read"} +common = {path = "./builtins_rust/common"} diff --git a/bash-5.1/builtins_rust/cd/src/lib.rs b/bash-5.1/builtins_rust/cd/src/lib.rs index bb10f8c..bc17200 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, - filename:* mut WORD_DESC + dest:libc::c_int, /* Place to redirect REDIRECTOR to, or ... */ + filename:* mut WORD_DESC /* filename to redirect to. */ } #[repr(C)] @@ -71,6 +71,7 @@ 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) => { @@ -298,28 +411,24 @@ 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 { () => { @@ -334,8 +443,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; @@ -346,14 +455,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; @@ -365,30 +474,32 @@ 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); } @@ -399,10 +510,11 @@ 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!(); @@ -410,7 +522,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; @@ -419,18 +531,20 @@ 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; - } - } else { - let c_str_cd = CString::new("cd").unwrap(); - dirname=get_working_directory(c_str_cd.as_ptr() as * mut c_char); + + +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); +} - /* 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; @@ -444,22 +558,22 @@ pub extern "C" fn r_bindpwd (no_symlinks:i32)->i32 { 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; @@ -469,7 +583,7 @@ pub extern "C" fn r_bindpwd (no_symlinks:i32)->i32 { /* 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); @@ -480,19 +594,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; @@ -511,24 +625,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 { @@ -543,13 +657,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!(); } @@ -557,20 +671,22 @@ 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 usize +4) as *mut c_char) as u8) == '\0' { + }else if char::from((*(*(*loptend).word).word) as u8) == '-' && char::from(*((((*(*loptend).word).word) as u8 +1) 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; @@ -581,23 +697,22 @@ 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() { - libc::printf(CString::new("%s\n").unwrap().as_ptr() as * const c_char,path); + println!("{:?}",path); } } - + libc::free (temp as * mut c_void); return r_bindpwd (no_symlinks); @@ -611,24 +726,25 @@ 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 { - libc::printf(CString::new("%s\n").unwrap().as_ptr() as * const c_char,dirname); + if (lflag & LCD_PRINTPATH!()) !=0{ + println!("{:?}", dirname); + } + return r_bindpwd (no_symlinks); } - 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 { - libc::printf(CString::new("%s\n").unwrap().as_ptr() as * const c_char,temp); + if temp != std::ptr::null_mut() && r_change_to_directory (temp, no_symlinks, xattrflag) !=0 + { + println!("{:?}", temp); return r_bindpwd (no_symlinks); } } @@ -645,21 +761,24 @@ 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; @@ -667,9 +786,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{ @@ -678,25 +797,28 @@ 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); @@ -704,19 +826,20 @@ pub extern "C" fn r_pwd_builtin (list:* mut WORD_LIST)->i32 { if directory != std::ptr::null_mut() { opt = EXECUTION_SUCCESS!(); - libc::printf(CString::new("%s\n").unwrap().as_ptr() as * const c_char,directory); + println!("{:?}",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!(); - } + } + } } @@ -725,8 +848,9 @@ 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; @@ -748,7 +872,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!()); @@ -761,7 +885,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; @@ -770,8 +894,10 @@ 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); @@ -781,31 +907,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); + if t == std::ptr::null_mut(){ + set_working_directory (tdir); + } else{ + libc::free (t as * mut c_void); + } } else { - libc::free (t as * mut c_void); + set_working_directory (tdir); } - } else { - set_working_directory (tdir); - } - + libc::free (tdir as * mut c_void); return 1; } @@ -813,7 +939,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; } @@ -825,28 +951,18 @@ 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/fg_bg/src/lib.rs b/bash-5.1/builtins_rust/fg_bg/src/lib.rs index bfb359b..56c9c81 100644 --- a/bash-5.1/builtins_rust/fg_bg/src/lib.rs +++ b/bash-5.1/builtins_rust/fg_bg/src/lib.rs @@ -340,7 +340,7 @@ macro_rules! IS_JOBCONTROL { #[macro_export] macro_rules! INVALID_JOB { ($j:expr) => { - $j <0 || $j >= js.j_jobslots || get_job_by_jid !($j) as u8 == 0 + $j <0 || $j >= js.j_jobslots || get_job_by_jid !($j) == std::ptr::null_mut() } } @@ -354,7 +354,7 @@ macro_rules! ISHELP { #[macro_export] macro_rules! CHECK_HELPOPT { ($l:expr) => { - if $l as u8 !=0 && (*$l).word as u8 !=0 && ISHELP!((*(*$l).word).word) == 0 + if $l !=std::ptr::null_mut() && (*$l).word !=std::ptr::null_mut() && ISHELP!((*(*$l).word).word) == 0 { builtin_help (); return EX_USAGE!(); @@ -397,11 +397,11 @@ 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 as u8 == 0{ + if loptend == std::ptr::null_mut(){ return r_fg_bg (loptend, 1); }else { let mut t:WORD_LIST=*loptend; - while t.next as u8 !=0{ + while t.next !=std::ptr::null_mut(){ t=*(t.next); } let cstr:&std::ffi::CStr=std::ffi::CStr::from_ptr((*(t.word)).word ); @@ -443,9 +443,9 @@ pub extern "C" fn r_bg_builtin (list:*mut WORD_LIST)->i32{ r = EXECUTION_FAILURE!(); } - if loptend as u8 !=0 { + if loptend !=std::ptr::null_mut() { let mut t:WORD_LIST=*loptend; - while t.next as u8 !=0 { + while t.next !=std::ptr::null_mut() { if r_fg_bg (&mut t, 0) == EXECUTION_FAILURE!(){ r = EXECUTION_FAILURE!(); } @@ -477,7 +477,7 @@ pub extern "C" fn r_fg_bg (list:*mut WORD_LIST, foreground:i32)->i32{ if INVALID_JOB !(job){ if job != DUP_JOB!(){ - if list as u8 != 0 { + 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 diff --git a/bash-5.1/builtins_rust/jobs/src/lib.rs b/bash-5.1/builtins_rust/jobs/src/lib.rs index 5c01627..fc30276 100644 --- a/bash-5.1/builtins_rust/jobs/src/lib.rs +++ b/bash-5.1/builtins_rust/jobs/src/lib.rs @@ -355,7 +355,7 @@ macro_rules! get_job_by_jid { #[macro_export] macro_rules! INVALID_JOB { ($j:expr) => { - $j <0 || $j >= js.j_jobslots || get_job_by_jid !($j) as u8 == 0 + $j <0 || $j >= js.j_jobslots || get_job_by_jid !($j) == std::ptr::null_mut() } } @@ -399,7 +399,7 @@ extern "C" { /* First do the replacement of job specifications with pids. */ - while l.next as u8 !=0 { + while l.next !=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); @@ -489,7 +489,7 @@ pub extern "C" fn r_jobs_builtin(list:*mut WORD_LIST)->i32{ return r_execute_list_with_replacements (loptend); } - if loptend as u8 ==0 { + if loptend ==std::ptr::null_mut() { if state == JSTATE_ANY!() { list_all_jobs (form); } else if state == JSTATE_RUNNING!() { @@ -501,11 +501,11 @@ pub extern "C" fn r_jobs_builtin(list:*mut WORD_LIST)->i32{ } let mut loptendt=*loptend; - while loptendt.next as u8 !=0 { + 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 as u8 == 0 || get_job_by_jid !(job) as u8 == 0 { + if (job == NO_JOB!()) || jobs == std::ptr::null_mut() || get_job_by_jid !(job) == std::ptr::null_mut() { sh_badjob ((*loptendt.word).word); any_failed+=1; } else if (job != DUP_JOB!()){ @@ -558,7 +558,7 @@ pub extern "C" fn r_disown_builtin (list:* mut WORD_LIST)->libc::c_int{ retval = EXECUTION_SUCCESS!(); /* `disown -a' or `disown -r' */ - if loptend as u8 == 0 && (all_jobs !=0 || running_jobs != 0) { + if loptend == std::ptr::null_mut() && (all_jobs !=0 || running_jobs != 0) { if nohup_only!=0{ nohup_all_jobs (running_jobs); } else{ @@ -569,14 +569,14 @@ pub extern "C" fn r_disown_builtin (list:* mut WORD_LIST)->libc::c_int{ } BLOCK_CHILD !(Some(&mut set), Some(&mut oset)); - if (loptend as u8 !=0 && legal_number ((*(*loptend).word).word, &mut pid_value) !=0 && pid_value == pid_value) { + 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 as u8 !=0 || INVALID_JOB!(job){ - if loptend as u8 !=0 { + if job == NO_JOB!() || jobs !=std::ptr::null_mut() || INVALID_JOB!(job){ + if loptend !=std::ptr::null_mut() { sh_badjob ((*(*loptend).word).word); }else { sh_badjob (CString::new("current").unwrap().as_ptr() as * mut c_char); @@ -591,9 +591,9 @@ pub extern "C" fn r_disown_builtin (list:* mut WORD_LIST)->libc::c_int{ UNBLOCK_CHILD !(Some(&oset)); - if loptend as u8 !=0 { + if loptend != std::ptr::null_mut() { let mut loptendt=*loptend; - while loptendt.next as u8 !=0 { + while loptendt.next !=std::ptr::null_mut() { loptendt = *loptendt.next; BLOCK_CHILD !(Some(&mut set), Some(&mut oset)); if legal_number ((*loptendt.word).word, &mut pid_value) !=0 && pid_value == pid_value { @@ -602,7 +602,7 @@ pub extern "C" fn r_disown_builtin (list:* mut WORD_LIST)->libc::c_int{ get_job_spec (&mut loptendt); } - if job == NO_JOB!() || jobs as u8 !=0 || INVALID_JOB!(job){ + if job == NO_JOB!() || jobs !=std::ptr::null_mut() || INVALID_JOB!(job){ sh_badjob ((*loptendt.word).word); diff --git a/bash-5.1/execute_cmd.c b/bash-5.1/execute_cmd.c index ecd509c..9d66af0 100644 --- a/bash-5.1/execute_cmd.c +++ b/bash-5.1/execute_cmd.c @@ -4737,7 +4737,7 @@ execute_builtin (builtin, words, flags, subshell) error_trap = 0; should_keep = 0; - r_execute_cmd(); + //r_execute_cmd(); /* The eval builtin calls parse_and_execute, which does not know about the setting of flags, and always calls the execution functions with flags that will exit the shell on an error if -e is set. If the @@ -4841,6 +4841,7 @@ execute_builtin (builtin, words, flags, subshell) executing_builtin++; executing_command_builtin |= builtin == command_builtin; result = ((*builtin) (words->next)); + // r_execute_cmd2(words->next); /* This shouldn't happen, but in case `return' comes back instead of longjmp'ing, we need to unwind. */ diff --git a/bash-5.1/rsbuiltins.h b/bash-5.1/rsbuiltins.h index f3b7f9b..f6f3be3 100644 --- a/bash-5.1/rsbuiltins.h +++ b/bash-5.1/rsbuiltins.h @@ -1,2 +1,4 @@ #include +#include "command.h" int r_execute_cmd(); +int r_execute_cmd2(WORD_LIST *l); diff --git a/bash-5.1/src/lib.rs b/bash-5.1/src/lib.rs index 874f7e6..39f431c 100644 --- a/bash-5.1/src/lib.rs +++ b/bash-5.1/src/lib.rs @@ -1,5 +1,42 @@ +use libc::{c_char, c_int, c_long}; +use std::ffi::CStr; +use std::str; + +#[repr(C)] +pub struct WORD_DESC { + pub word : *mut c_char, + pub flags : c_int +} + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct WORD_LIST { + next : *mut WORD_LIST, + word : *mut WORD_DESC +} + + +//#[link(name = "")] +//extern { + // pub fn printf( #[no_mangle] pub extern "C" fn r_execute_cmd() { - println!("hello"); + //println!("hello"); + //common::builtin_error("test error") } +#[no_mangle] +pub extern "C" fn r_execute_cmd2(l : *mut WORD_LIST) -> i32 { + unsafe { + let mut it : *mut WORD_LIST = l; + while std::ptr::null() != it { + //let mut a = (&((* ((*l).word)).word) ); + let mut a :*mut c_char =( *(*it).word).word; + let c_str: &CStr = CStr::from_ptr(a); + let str_slice: &str = c_str.to_str().unwrap(); + println! ("word is {:?}", str_slice); + it = (*it).next; + } + } + 0 +} diff --git a/record.txt b/record.txt index 9b24089..32107ab 100644 --- a/record.txt +++ b/record.txt @@ -10,3 +10,4 @@ 9 10 11 +12 -- Gitee