brian@radio.astro.utoronto.ca (Brian Glendenning) (06/28/89)
I believe I may have found another incompatibility between sh and bash (maybe I should get brave and call it a bug :-). sh: $ del() { /bin/rm -i $* ; } $ touch junk $ del junk rm: remove junk? ^C $ echo $* $ bash: $ del() { /bin/rm -i $* ; } $ touch junk $ del junk rm: remove junk? ^C $ echo $* junk $ This would not be so bad, except that it appears that if $* is set it is not reset properly upon entry to other shell functions (at least), e.g.: bash: $ del() { /bin/rm -i $* ; } $ lf() { /bin/ls -F $* ; } $ touch junk $ del junk rm: remove junk? ^C $ mv junk trash $ lf junk not found $ -- Brian Glendenning - Radio astronomy, University of Toronto brian@radio.astro.utoronto.ca uunet!utai!radio!brian glendenn@utorphys.bitnet -- Brian Glendenning - Radio astronomy, University of Toronto brian@radio.astro.utoronto.ca uunet!utai!radio!brian glendenn@utorphys.bitnet
chet@kiwi.CWRU.EDU (Chet Ramey) (07/01/89)
In article <BRIAN.89Jun27235835@radio.astro.utoronto.ca> brian@radio.astro.utoronto.ca (Brian Glendenning) writes: > >I believe I may have found another incompatibility between sh and >bash (maybe I should get brave and call it a bug :-). Be brave; it is a bug. >bash: >$ del() { /bin/rm -i $* ; } >$ lf() { /bin/ls -F $* ; } >$ touch junk >$ del junk >rm: remove junk? ^C >$ mv junk trash >$ lf >junk not found >$ What is happening is that a context is getting pushed, but not popped (a bash context consists of the `dollar variables' and any local variables, as well as a particular value of variable_context, cf. push_context() and pop_context() in builtins.c). Ordinarily, during command execution, this is not a problem; the appropriate context is restored when the child forked to execute the command exits. However, bash executes functions and builtins with no redirections directly in the main shell, and fails to add unwind protects to restore the proper state if interrupted. Once you digest that :-), a fix is easy (though it might not be the Officially Blessed fix). With the following diffs applied, here is what happens to Brian's example: cwns6$ del() { /bin/rm -i $* ; } cwns6$ lf() { /bin/ls -F $* ; } cwns6$ touch foo cwns6$ del foo /bin/rm: remove foo? ^C cwns6$ mv foo bar cwns6$ lf bar cwns6$ Here are the diffs to execute_cmd.c: *** bash-1.01/execute_cmd.c Fri Jun 23 12:55:22 1989 --- src-1.01/execute_cmd.c Fri Jun 30 14:08:37 1989 *************** *** 633,641 **** --- 633,646 ---- else { + extern int pop_context(), dispose_command(); COMMAND *tc = (COMMAND *)copy_command (var->value); push_context (); + add_unwind_protect(dispose_command, (char *)tc); + add_unwind_protect(pop_context, (char *) NULL); remember_args (words->next, 0); result = execute_command (tc); pop_context (); dispose_command (tc); + remove_unwind_protect(); + remove_unwind_protect(); Chet Ramey "We are preparing to think about contemplating Network Services Group, CWRU preliminary work on plans to develop a chet@cwjcc.INS.CWRU.Edu schedule for producing the 10th Edition of the Unix Programmers Manual." -- Andrew Hume