accwai@WATMATH.WATERLOO.EDU (Andy Wai) (07/15/89)
The following was discovered by one of the users around here: Script started on Fri Jul 14 13:23:21 1989 % bash <== invoke bash here watmath[1]$ function CAT <== define function CAT bash>{ bash>/bin/cat $@ bash>} watmath[2]$ CAT hi Hi! <== this one is fine watmath[3]$ CAT hi >log <== did an "ls" and "exit" here, not echoed % cat log <== back to csh, look at the log file Hi! watmath[4]$ ls <== "ls" and "exit" shows up in the log file! hi log typescript watmath[5]$ exit % exit script done on Fri Jul 14 13:25:36 1989 Once the output of a function is redirected, it stays redirected after the function is completed. This happens on all architectures we have. It was discovered in version 1.01 and still exist in 1.02. Thanks. Andy Wai Math. Faculty Computing Facility U. of Waterloo
chet@kiwi.CWRU.EDU (Chet Ramey) (07/20/89)
In article <8907141748.AA14752@watmath.waterloo.edu> accwai@WATMATH.WATERLOO.EDU (Andy Wai) writes: >Once the output of a function is redirected, it stays redirected after >the function is completed. This happens on all architectures we have. >It was discovered in version 1.01 and still exist in 1.02. This is kind of a weird problem. Here is a trail of what happens: 1. execute_command gets called with the function as the command and an output redirection spec. 2. it calls do_redirections to do the redirections and create the redirection_undo_list, then copies that to my_undo_list 3. execute_simple_command gets called, and after deciding that the command is a function, calls execute_command again on the list of commands that make up the function body. 4. execute_command calls do_redirections again and overwrites redirection_undo_list and my_undo_list. Bang. When the function completes, there is nothing to undo, so nothing is undone. The fix is to save and restore the undo list around the call to the function, so that execute_command can zero out redirection_undo_list and not have to worry about it. This seems to work for multiple functions redirecting output to multiple places as well: kiwi$ type CAT CAT is a function CAT () { /bin/cat $@ <--- just let inputs pass through } kiwi$ type CAT2 CAT2 is a function CAT2 () { CAT $@ ; CAT $@ >log2 <---- cat to screen and to log file } kiwi$ CAT hi thththththththththt kiwi$ CAT2 hi hi hi > log <---- same stuff should end up in log and log2 kiwi$ cat log thththththththththt thththththththththt thththththththththt kiwi$ CAT log2 thththththththththt thththththththththt thththththththththt These diffs seem to work, but they may depend on when the compiler allocates storage for func_redirection_undo_list (gcc does it OK for me). *** bash-1.02/execute_cmd.c Wed Jul 19 17:26:45 1989 --- execute_cmd.c Wed Jul 19 18:30:23 1989 *************** *** 621,624 **** --- 622,626 ---- { int result = EXECUTION_FAILURE; + REDIRECT *func_redirection_undo_list = (REDIRECT *) NULL; if (do_redirections (simple_command->redirects, 1, 1) == 0) { *************** *** 641,645 **** --- 643,649 ---- { COMMAND *tc = (COMMAND *)copy_command (var->value); + extern int dispose_command(), pop_context(); + func_redirection_undo_list = (REDIRECT *) copy_redirects (redirection_undo_list); push_context (); *************** *** 658,662 **** { } ! do_redirections (reverse_list (redirection_undo_list), 1, 0); return (result); } --- 666,670 ---- { } ! do_redirections (reverse_list (func_redirection_undo_list), 1, 0); return (result); } 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