emil%chem@UCSD.EDU (Emil M. Scoffone) (06/26/89)
GNU program: Bash 1.01 Machine: Compaq Deskpro 386/16 Operating System: System V/386 Release 3.2 (vendor: Bell Technologies) Compiler: GNU C, version 1.35, with GNU as and ld. I defined a new machine name `i386' in Makefile, for PCs. The UNIXPC operating system type seems to be for Xenix, so I used the SYSV-i386 combination for distinguishing a PC based machine running sysV. Mail (if needed) to escoffon@ucsd.edu. **************************************** These are bugs I found while installing bash: ---------------------------------------- in `shell.c': SIGVTALRM and SIGPROF are undefined signals under sysv. Fix: used #ifdef's to selectively include the signals. ---------------------------------------- in `general.c': in `dup2': fDUPFD undeclared Fix: changed to F_DUPFD in `gethostname': namelen undeclared Fix: changed to namlen ---------------------------------------- in `parse.y': (this is a warning, I think) in `decode_prompt_string': assignment needs a cast (line 1516) Fix: added `extern char *index();' declaration. Note that people who load with libPW.a should probably redefine `index' to `strchr', since there is a `index' routine in that library. ---------------------------------------- Note also that I had to change the name `unwind_correct.c' to `uw_correct.c', since sysV takes at most 14 characters for filenames. I subscribe to your opinions on the subject. **************************************** These are bugs I found while running bash: ---------------------------------------- When a command is run that returns a nonzero exit code xxx, bash prints the message Signal xxx (core dumped) This is because `struct wait' is incorrectly defined in `jobs.h': the low and high byte of the return value from wait(2) are swapped. Fix: rewrote `struct wait' to give the right byte order. ---------------------------------------- **************************************** In addition to the bug fixes, I made some other (convenience) changes: ---------------------------------------- `shell_ulimit' was slightly modified to be more in line with the description of ulimit(2) on my system. ---------------------------------------- On my computer, ^H by default acts as the `erase' character; bash uses RUBOUT for this purpose. In order to be consistent, I changed the keymap for ^H from `rl_backward' to `rl_rubout'. The macro CTRLH_SAME_AS_RUBOUT (defined in `readline.h') can be used to turn the new mapping on or off. ---------------------------------------- I use shl(1) in lieu of job control under SysV. This implies that one cannot turn ISIG off, since the terminal driver interprets the `switch' character and signals shl. By default, the readline package will turn ISIG off when NOJOBS is defined, which makes it impossible to switch out of bash. The macro WANT_SHL (defined in `readline.h') can be used to turn the switching on or off under sysV. ---------------------------------------- **************************************** I also made some minor changes here and there, which are not worth a long-winded report. The rest of the file shows all the differences between my modified bash files and the 1.01 distribution. diff dist-bash/FEATURES old-bash/FEATURES diff dist-bash/LICENSE old-bash/LICENSE diff dist-bash/Makefile old-bash/Makefile 30c30 < MAINTAINER = '"escoffon@ucsd.edu"' --- > MAINTAINER = '"bfox@ai.mit.edu"' 34c34 < DESTDIR = /usr/local/bin --- > DESTDIR = /usr/gnu/bin 39,40c39,40 < # SUN3, SUN4, SUN386i, i386, VAX, SONY, CONVEX, HP, HP9KS300 < TARGET = i386 --- > # SUN3, SUN4, SUN386i, VAX, SONY, CONVEX, HP, HP9KS300 > TARGET = SUN3 45c45 < OS = SYSV --- > OS = SUNOS4 73c73 < TERMCAP = curses --- > TERMCAP = termcap 99c99 < SPROMPT = '"${PROGRAM}> "' --- > SPROMPT = '"${PROGRAM}>"' 112,113c112,113 < #MALLOC = $(ALLOC_SOURCE)malloc-rcheck.o < MALLOC= $(ALLOC_SOURCE)malloc.o --- > MALLOC = $(ALLOC_SOURCE)malloc-rcheck.o > #MALLOC= $(ALLOC_SOURCE)malloc.o 125c125 < uw_protect.c --- > unwind_protect.c 137c137 < braces.o uw_protect.o --- > braces.o unwind_protect.o diff dist-bash/README old-bash/README diff dist-bash/alias.c old-bash/alias.c diff dist-bash/alias.h old-bash/alias.h diff dist-bash/braces.c old-bash/braces.c diff dist-bash/builtins.c old-bash/builtins.c 25,26d24 < #if !(defined(SYSV) && defined(i386)) < #include <sys/resource.h> 27a26 > #include <sys/resource.h> 29d27 < #endif 2424d2421 < #if !(defined(SYSV) && defined(i386)) 2426d2422 < #endif /* SYSV && i386 */ 2439,2441d2434 < #ifdef i386 < return (ulimit (1, 0)); < #else /* i386 */ 2443d2435 < #endif /* i386 */ diff dist-bash/builtins.h old-bash/builtins.h diff dist-bash/config.h old-bash/config.h 6,9d5 < #ifdef __GNUC__ < #define alloca __builtin_alloca < #endif < 68a65 > diff dist-bash/copy_cmd.c old-bash/copy_cmd.c diff dist-bash/dispose_cmd.c old-bash/dispose_cmd.c diff dist-bash/emacs_keymap.c old-bash/emacs_keymap.c diff dist-bash/execute_cmd.c old-bash/execute_cmd.c diff dist-bash/flags.c old-bash/flags.c diff dist-bash/flags.h old-bash/flags.h diff dist-bash/funmap.c old-bash/funmap.c diff dist-bash/general.c old-bash/general.c 28,30d27 < #if defined(SYSV) && defined(i386) < #include <string.h> < #else 32d28 < #endif /* SYSV && i386 */ 370c366 < int dup2 (f, t) int f, t; { close (t); return (fcntl (f, F_DUPFD, t)); } --- > int dup2 (f, t) int f, t; { close (t); return (fcntl (f, fDUPFD, t)); } 382c378 < name[namlen - 1] = '\0'; --- > name[namelen - 1] = '\0'; diff dist-bash/general.h old-bash/general.h diff dist-bash/glob.c old-bash/glob.c 54,56d53 < #ifdef __GNUC__ < #define alloca __builtin_alloca < #else 58d54 < #endif diff dist-bash/hash.c old-bash/hash.c diff dist-bash/hash.h old-bash/hash.h diff dist-bash/history.c old-bash/history.c diff dist-bash/history.h old-bash/history.h diff dist-bash/inform old-bash/inform diff dist-bash/jobs.c old-bash/jobs.c diff dist-bash/jobs.h old-bash/jobs.h 9,14c9 < union wait { < struct { < unsigned char low; unsigned char high; < } bytes; < unsigned short word; < }; --- > union wait { struct { char high; char low; } bytes; short word; }; 17c12 < #define w_termsig bytes.low & ~0200 --- > #define w_termsig bytes.low 20c15 < #define w_coredump bytes.low & 0200 --- > #define w_coredump w_termsig & 0x7f 110a106 > diff dist-bash/keymaps.c old-bash/keymaps.c diff dist-bash/longest_signal old-bash/longest_signal diff dist-bash/mail-shell old-bash/mail-shell diff dist-bash/mailcheck.c old-bash/mailcheck.c 27,30d26 < #ifdef __GNUC__ < #define alloca __builtin_alloca < #endif < diff dist-bash/make_cmd.c old-bash/make_cmd.c diff dist-bash/newversion.c old-bash/newversion.c diff dist-bash/nojobs.c old-bash/nojobs.c diff dist-bash/parse.y old-bash/parse.y 1404d1403 < extern char *index (); diff dist-bash/print_cmd.c old-bash/print_cmd.c diff dist-bash/readline.c old-bash/readline.c 85d84 < #ifndef WANT_SHL 90d88 < #endif 567,569d566 < #ifdef CTRLH_SAME_AS_RUBOUT < keymap[CTRL('H')] = rl_rubout; < #else 571d567 < #endif diff dist-bash/readline.h old-bash/readline.h 89,101d88 < /* escoffon@ucsd.edu < If on, then readline does not turn signal generation off when in SysV. < The idea is that ISIG is kept on, and therefore a ^Z will signal the < shell layer manager, shl(1). */ < #if defined(SYSV) < #define WANT_SHL < #endif < < /* escoffon@ucsd.edu < If on, then readline maps backspaces (^H) and delete to perform < the same operation. */ < #define CTRLH_SAME_AS_RUBOUT < diff dist-bash/shell.c old-bash/shell.c 737,742c737 < #ifdef SIGVTALRM < SIGVTALRM, < #endif < #ifdef SIGPROF < SIGPROF, < #endif --- > SIGVTALRM, SIGPROF, diff dist-bash/shell.h old-bash/shell.h diff dist-bash/subst.c old-bash/subst.c diff dist-bash/test.c old-bash/test.c diff dist-bash/trap.c old-bash/trap.c diff dist-bash/trap.h old-bash/trap.h diff dist-bash/uw_protect.c old-bash/uw_protect.c diff dist-bash/variables.c old-bash/variables.c 28,31d27 < #ifdef __GNUC__ < #define alloca __builtin_alloca < #endif < diff dist-bash/variables.h old-bash/variables.h diff dist-bash/version.h old-bash/version.h diff dist-bash/vi_keymap.c old-bash/vi_keymap.c
emil%chem@UCSD.EDU (Emil M. Scoffone) (07/17/89)
To: bug-bash@ai.mit.edu BASH version: 1.02 Machine: Sun 3/160 OpSys: SunOS 3.2 (4.2BSD) Compiler: Sun's native cc ------------------------------------------------------------ Description of bug: Hitting ^D at the beginning of line results in the following message: Segmentation fault (core dumped) and the shell crashes. This seems to be independent of the value of 'IGNOREEOF' and 'ignoreeof'. ------------------------------------------------------------ Probable Reason: I ran BASH in dbx, and found out that 'readline' returns EOF coerced to a (char *) on its second invocation after it has seen a valid EOF. On the other hand, 'yy_readline_get' never checks if the value that 'readline' returns in 'current_readline_line' is a valid pointer. When it gets to 'strlen' in the 'xrealloc' call, BASH bombs out. ------------------------------------------------------------ My Fix: I edited 'parse.y' to include a statement that checks if 'current_readline_line' is (char *) EOF: 08:16:45 pogo(6) diff -c parse.y parse.y~ *** parse.y Mon Jul 17 08:16:44 1989 --- parse.y~ Mon Jul 17 08:05:13 1989 *************** *** 429,439 **** else current_readline_line = readline (current_readline_prompt); - if (current_readline_line == (char *) EOF) { - current_readline_line = (char *)NULL; - return (EOF); - } - current_readline_line_index = 0; current_readline_line = (char *)xrealloc (current_readline_line, --- 429,434 ---- 08:16:50 pogo(7) ------------------------------------------------------------ I have also seen erratic behaviour on ^D on a Compaq 386 running System V, but I haven't had time to look at it in great detail.
emil%chem@UCSD.EDU (Emil M. Scoffone) (07/22/89)
To: bug-bash@ai.mit.edu GNU program: Bash 1.02 Machine: Compaq Deskpro 386/16 Operating System: System V/386 Release 3.2 (vendor: Bell Technologies) Compiler: GNU C, version 1.35, with GNU as and ld. **************************************** These are bugs I found while installing bash: ---------------------------------------- in `shell.c': on line 305: 'job_control' undefined. Fix: changed line 304 from #ifndef JOB_CONTROL to #ifndef NOJOBS ---------------------------------------- in `variables.c' and `readline.c': `struct pwd' should be `struct passwd' ---------------------------------------- in `readline.c': `sigsetmask' is referenced, but there is no such system call on my UNIX. Fix: I defined a dummy `sigsetmask' that does nothing. I was too lazy to write one that mimicks the behaviour of BSD `sigsetmask' ---------------------------------------- in 'glob.c': I added an #ifdef to use the GNU builtin alloca. ---------------------------------------- **************************************** These are bugs I found while running bash: ---------------------------------------- The shell does incorrectly reports exit codes from a killed job. This is because a couple of masks were defined incorrectly in `jobs.h'. I also parenthesized two expressions in 'nojobs.h'. ---------------------------------------- I get segmentation violations or memory errors, and the shell bombs, when I hit ^D. This is the same bug I reported a couple of days ago on a Sun 3/160, and I fixed it the same way (added a few lines to 'parse.y'). ---------------------------------------- **************************************** The following is a list of modifications to the source files: ------------------------------------------------------------ diff -c shell.c shell.c~ *** shell.c Tue Jul 11 20:33:11 1989 --- shell.c~ Fri Jul 21 15:01:20 1989 *************** *** 301,307 **** else { interactive = 0; ! #ifndef NOJOBS job_control = 0; #endif } --- 301,307 ---- else { interactive = 0; ! #ifndef JOB_CONTROL job_control = 0; #endif } ------------------------------------------------------------ diff -c variables.c variables.c~ *** variables.c Tue Jul 11 21:02:14 1989 --- variables.c~ Fri Jul 21 15:01:20 1989 *************** *** 26,31 **** --- 26,35 ---- #include "flags.h" #include "version.h" + #ifdef SYSV + struct pwd *getpwuid (), *getpwent (); + #endif + /* The list of shell variables that the user has created, or that came from the environment. */ SHELL_VAR *variable_list; ------------------------------------------------------------ diff -c ./lib/readline.c ./lib/readline.c~ *** ./lib/readline.c Fri Jul 21 15:07:21 1989 --- ./lib/readline.c~ Fri Jul 21 15:02:42 1989 *************** *** 58,63 **** --- 58,66 ---- #include <sys/stat.h> #include <pwd.h> + #ifdef SYSV + struct pwd *getpwuid (), *getpwent (); + #endif #define HACK_TERMCAP_MOTION *************** *** 272,284 **** *old_ttou = (Function *)NULL, *old_ttin = (Function *)NULL, *old_cont = (Function *)NULL; - - #ifdef SYSV - void sigsetmask(mask) - int mask; - { - } - #endif SYSV /* Handle an interrupt character. */ static --- 275,280 ---- ------------------------------------------------------------ diff -c jobs.h jobs.h~ *** jobs.h Mon Jul 17 22:14:14 1989 --- jobs.h~ Fri Jul 21 15:01:20 1989 *************** *** 17,26 **** #define WSTOPPED 0177 #define w_status word ! #define w_termsig bytes.low & 0x7f ! #define w_coredump bytes.low & ~0x7f #define w_stopsig bytes.high #define w_retcode bytes.high #define WIFEXITED(wstat) ((wstat).bytes.low == 0) #define WIFSTOPPED(wstat) ((wstat).bytes.low == 0177) #define WIFTERMINATED(wstat) ((wstat).bytes.high == 0) --- 17,26 ---- #define WSTOPPED 0177 #define w_status word ! #define w_termsig bytes.low & ~0x7f #define w_stopsig bytes.high #define w_retcode bytes.high + #define w_coredump w_termsig & 0x7f #define WIFEXITED(wstat) ((wstat).bytes.low == 0) #define WIFSTOPPED(wstat) ((wstat).bytes.low == 0177) #define WIFTERMINATED(wstat) ((wstat).bytes.high == 0) ------------------------------------------------------------ diff -c nojobs.c nojobs.c~ *** nojobs.c Mon Jul 17 22:14:43 1989 --- nojobs.c~ Fri Jul 21 15:11:22 1989 *************** *** 144,151 **** /* Default return value. */ return_val = status.w_retcode & 0x7f; ! if ((status.w_termsig) != 0 && ! (status.w_termsig) != WSTOPPED) { #ifndef SYSV extern char *sys_siglist[]; fprintf (stderr, "%s", sys_siglist[status.w_termsig]); --- 144,151 ---- /* Default return value. */ return_val = status.w_retcode & 0x7f; ! if (status.w_termsig != 0 && ! status.w_termsig != WSTOPPED) { #ifndef SYSV extern char *sys_siglist[]; fprintf (stderr, "%s", sys_siglist[status.w_termsig]); ------------------------------------------------------------ diff -c glob.c glob.c~ *** glob.c Tue Jul 11 21:35:20 1989 --- glob.c~ Fri Jul 21 15:02:19 1989 *************** *** 51,63 **** #ifdef sparc #include <alloca.h> #else - - #ifdef __GNUC__ - #define alloca __builtin_alloca - #else extern char *alloca (); - #endif - #endif /* sparc */ extern char *malloc (), *realloc (); --- 51,57 ---- ------------------------------------------------------------ diff -c parse.y parse.y~ *** parse.y Mon Jul 17 22:19:06 1989 --- parse.y~ Fri Jul 21 15:11:03 1989 *************** *** 429,440 **** else current_readline_line = readline (current_readline_prompt); - if (current_readline_line == (char *) EOF) - { - current_readline_line = (char *)NULL; - return (EOF); - } - current_readline_line_index = 0; current_readline_line = (char *)xrealloc (current_readline_line, --- 429,434 ----
bfox@AUREL.CALTECH.EDU (Brian Fox) (07/22/89)
Date: Fri, 21 Jul 89 15:14:08 PDT From: emil%chem@ucsd.edu (Emil M. Scoffone) To: bug-bash@ai.mit.edu GNU program: Bash 1.02 Machine: Compaq Deskpro 386/16 Operating System: System V/386 Release 3.2 (vendor: Bell Technologies) Compiler: GNU C, version 1.35, with GNU as and ld. **************************************** These are bugs I found while installing bash: ---------------------------------------- The shell does incorrectly reports exit codes from a killed job. This is because a couple of masks were defined incorrectly in `jobs.h'. I also parenthesized two expressions in 'nojobs.h'. ---------------------------------------- Thank you for your clear bug report. I recently received a fix for the 386 problems. It has to do with the byte order defined in the "wait" structure. Please try using this jobs.h file, and tell me if it works. ---------------------------------------- File: /usr/gnu/src/bash/jobs.h ---------------------------------------- /* jobs.h -- structures and stuff used by the jobs.c file. */ #if !defined (SYSV) || defined (UNIXPC) #include <sys/wait.h> #else #if defined (i386) || defined (ATT3B) || defined (ATT386) union wait { struct { unsigned char low; unsigned char high; } bytes; short word; }; #define WSTOPPED 0177 #define w_status word #define w_termsig bytes.low & ~0x7f #define w_stopsig bytes.high #define w_retcode bytes.high #define w_coredump w_termsig & 0x7f #define WIFEXITED(wstat) ((wstat).bytes.low == 0) #define WIFSTOPPED(wstat) ((wstat).bytes.low == 0177) #define WIFTERMINATED(wstat) ((wstat).bytes.high == 0) #else /* i386 || ATT3B || ATT386 */ #ifdef HPUX union wait { int w_status; /* used in syscall */ /* Terminated process status. */ struct { unsigned short w_Fill1 : 16, /* high 16 bits unused */ w_Retcode : 8, /* exit code if w_termsig==0 */ w_Coredump : 1, /* core dump indicator */ w_Termsig : 7; /* termination signal */ } w_T; /* Stopped process status. Returned only for traced children unless requested with the WUNTRACED option bit. */ struct { unsigned short w_Fill2 : 16, /* high 16 bits unused */ w_Stopsig : 8, /* signal that stopped us */ w_Stopval : 8; /* == W_STOPPED if stopped */ } w_S; }; #define w_termsig w_T.w_Termsig #define w_coredump w_T.w_Coredump #define w_retcode w_T.w_Retcode #define w_stopval w_S.w_Stopval #define w_stopsig w_S.w_Stopsig #define WSTOPPED 0177 #define WIFSTOPPED(x) (((x) . w_stopval) == WSTOPPED) #define WIFEXITED(x) ((! (WIFSTOPPED (x))) && (((x) . w_termsig) == 0)) #define WIFSIGNALED(x) ((! (WIFSTOPPED (x))) && (((x) . w_termsig) != 0)) #endif /* HPUX */ #endif /* i386 || ATT3B || ATT386 */ #endif /* !defined (SYSV) || defined (UNIXPC) */ /* I looked it up. For pretty_print_job (). The real answer is 24. */ #define LONGEST_SIGNAL_DESC 20 /* We keep an array of jobs. Each entry in the array is a linked list of processes that are piped together. The first process encountered is the group leader. */ /* Each child of the shell is remembered in a STRUCT PROCESS. A chain of such structures is a pipeline. The chain is circular. */ typedef struct process { struct process *next; /* Next process in the pipeline. A circular chain. */ int pid; /* Process ID. */ union wait status; /* The status of this command as returned by wait. */ int running; /* Non-zero if this process is running. */ char *command; /* The particular program that is running. */ } PROCESS; /* A description of a pipeline's state. */ typedef enum { JRUNNING, JSTOPPED, JDEAD, JMIXED } JOB_STATE; #define JOBSTATE(job) (jobs[(job)]->state) typedef struct job { char *wd; /* The working directory at time of invocation. */ PROCESS *pipe; /* The pipeline of processes that make up this job. */ int pgrp; /* The process ID of the process group (necessary). */ int foreground; /* Non-zero if this is running in the foreground. */ int notified; /* Non-zero if already notified about job state. */ JOB_STATE state; /* The state that this job is in. */ #ifdef JOB_CONTROL COMMAND *deferred; /* Commands that will execute when this job is done. */ #endif } JOB; #define NO_JOB -1 /* An impossible job array index. */ #define DUP_JOB -2 /* A possible return value for get_job_spec (). */ /* Stuff from the jobs.c file. */ extern int last_made_pid; extern int current_job, previous_job; extern int asynchronous_notification; extern JOB **jobs; extern int job_slots; ----------------------------------------
schene@UUNET.UU.NET (Tony Schene) (07/26/89)
Version: #define VERSION 1.02 Hardware: Sun 4/280 OS: SunOS 4.0.2 with Prisma enhancements and bug fixes Compiler: Sun cc with Prisma bug fixes and enhancements Bug: bash crashes if ^D is input Repeat by: 1) Start up bash 2) Type ^D Comments: The problem is in yy_readline_get() in line 430 of parse.y, on the call to readline(). Readline() returns -1 on EOF, but this is not checked for, and the -1 is later passed to strlen() on line 435. Instant death. I don't have a clue as to how to propagate this back up gracefully, but I'm sure you do. Hope this helps.
pwolfe@kailand.kai.com (Patrick Wolfe) (12/03/89)
System: Sequent Balance B8 OS: Sequent Dynix (BSD 4.2) version: 1.04 I picked up and started using bash this week and found a few problems. First, there appears to be a bug in the malloc routines. When I compiled bash with the supplied malloc, it would die with "free: invalid argument" after the following command sequence was executed: $ lf ~partial-username<tab> $ lf ~partial-username<tab> The first command would work, but the second one would kill bash. When I recompiled using the system's malloc, everything seems to work okay. The second problem is that readline seems to trash the command line if the TERMCAP for the current terminal has the "IC" capability in it. It is adding one extra blank for every character inserted (including one for the asterisk at the beginning of an edited line). Also, bash allows multi line prompts, but readline has problems when one is used, since it likes to jump to the begining of the current line and rewrite the prompt and beginning of the command. I would like to commend all those who've been working on bash and readline so far. I plan to continue using bash, and to try to find and fix any bugs I can. The "vi mode" simply blows away TCSH. -- Patrick Wolfe System Manager, Kuck & Associates work: pwolfe@kailand.kai.com or uunet!kailand!pwolfe home: pat@pawnix.kai.com or uunet!kailand!pawnix!pat
chet@cwns1.CWRU.EDU (Chet Ramey) (12/04/89)
In article <8912030428.AA01426@kailand.kai.com> pwolfe@kailand.kai.com (Patrick Wolfe) writes: >First, there appears to be a bug in the malloc routines. When I compiled bash >with the supplied malloc, it would die with "free: invalid argument" after >the following command sequence was executed: > > $ lf ~partial-username<tab> > $ lf ~partial-username<tab> > >The first command would work, but the second one would kill bash. When I >recompiled using the system's malloc, everything seems to work okay. This is a problem with YP (this is just one of many problems with YP) and the password routines that interact with it. These YP routines keep a socket open to the YP server, and close and reopen it when they think they need to (which is only right *some* of the time). Based on this assumption, the routines keep a pointer into the data returned from the YP server. When you do a `setpwent', setpwent frees up this storage if it thinks it needs to. This isn't always right, and you end up freeing freed storage. The Dynix free () allows you to free freed blocks; the bash free () doesn't. I tend to think the fault is with the Dynix free () and the YP routines. Chet Ramey -- Chet Ramey Network Services Group "Where's my froggie?" Case Western Reserve University chet@ins.CWRU.Edu
tchrist@convex.COM (Tom Christiansen) (12/08/89)
In article <8912030428.AA01426@kailand.kai.com> pwolfe@kailand.kai.com (Patrick Wolfe) writes: >I would like to commend all those who've been working on bash and readline so >far. I plan to continue using bash, and to try to find and fix any bugs I can. >The "vi mode" simply blows away TCSH. Well, it's nice, but it's not as complete a vi as ksh's vi mode, which is too bad. I also like the way tcsh allows ^W to back up to things like / and +, not just to white space. And I miss the asynchronous notification of tcsh and csh that's also lacking in ksh. I've been told by devout ksh users that it's missing autoload functions. --tom Tom Christiansen {uunet,uiucdcs,sun}!convex!tchrist Convex Computer Corporation tchrist@convex.COM "EMACS belongs in <sys/errno.h>: Editor too big!"
trost@reed.bitnet (Bill Trost) (12/09/89)
>I've been told by devout ksh users that it's missing autoload functions. Hah, you friends just don't know how to write ksh. I did the same thing with bash with a few minutes playing. Presumably, the ksh mechanism is equivalent. Anyone know how to do this without a tmp file? ". <<" doesn't work. autoload() { echo $1 \(\) \{ echo . $2 2\>\&1 \; . $2 \} > /tmp/au.$$ . /tmp/au.$$ rm /tmp/au.$$ } Sample use (spam should be defined in ~/spam): bash% autoload spam ~/spam bash% type spam spam is a function spam() { echo . /u/trost/spam 2>&1 ; . /u/trost/spam } bash% spam . /u/trost/spam /u/trost/spam: No such file or directory trost%reed@tektronix.tek.com -- Bill Trost trost@reed.bitnet, but probably trost%reed@tektronix.tek.com
anders@digre.uio.no (Anders Ellefsrud) (12/14/89)
> >I've been told by devout ksh users that it's missing autoload functions. > > autoload() { > echo $1 \(\) \{ echo . $2 2\>\&1 \; . $2 \} > /tmp/au.$$ > . /tmp/au.$$ > rm /tmp/au.$$ > } > I see a few problems with that function. I think this is better: autoload() { eval `echo "$1" "() { args=\$@ ; . $2 ; set -- \$args; $1 \$@ }"` } Note: I said BETTER, not PERFECT! It will not handle funny arguments like 'foo bar'. Usage: autoload foo ~/lib/the_foo_function . . . foo bar ... works as expected, but foo 'gaz onk' does not. --- anders@ifi.uio.no
bfox@sbphy.ai.mit.edu (Brian Fox) (12/14/89)
Date: 13 Dec 89 17:28:36 GMT
From: mcsun!sunic!nuug!ifi!digre!anders@uunet.uu.net (Anders Ellefsrud)
References: <8912030428.AA01426@kailand.kai.com>, <3749@convex.UUCP>
Sender: bug-bash-request@prep.ai.mit.edu
> >I've been told by devout ksh users that it's missing autoload functions.
Please send documentation on "autoload functions".
Brian
chet@cwns1.CWRU.EDU (Chet Ramey) (12/15/89)
In article <8912132157.AA04187@sbphy.Ucsb.EDU> bfox@sbphy.ai.mit.edu (Brian Fox) writes: > > Date: 13 Dec 89 17:28:36 GMT > From: mcsun!sunic!nuug!ifi!digre!anders@uunet.uu.net (Anders Ellefsrud) > References: <8912030428.AA01426@kailand.kai.com>, <3749@convex.UUCP> > Sender: bug-bash-request@prep.ai.mit.edu > > > >I've been told by devout ksh users that it's missing autoload functions. > >Please send documentation on "autoload functions". When you declare a function `autoload', it is marked as `undefined', and its definition is deferred until its first use. When such a function is referenced for the first time, a search is made of the `FPATH', a colon-separated list of directories just like $PATH, for a file whose name is the same as the function. If found, the file is then read in as if it had been the argument to a `.' command, and the function is executed. This is, I guess, how you get function libraries for doing shell programming. `autoload' is really a predefined alias for `typeset -fu' Here are two functions that will do pretty much the same thing for bash, with only a couple of differences. You need two fixes for bash to make this work `right': the fix for "$@" and a fix to stop the `.' command from blowing away the dollar variables unconditionally (ksh assigns extra arguments to `.' to the dollar variables, but leaves them alone if there are no extra args). `autoload' does the whole deal: handle multiple arguments, parse $FPATH, and so on. It calls `aload', which is a descendent of Bill Trost's `autoload' function, for each argument that it finds. An autoloaded function will be loaded from its source file on first reference, its definition will be replaced by the one in the source file, then the new definition will be run. This is about the best you can do without source support. Chet Ramey # # An almost ksh-compatible `autoload'. A function declared as `autoload' will # be read in from a file the same name as the function found by searching the # $FPATH (which works the same as $PATH), then that definition will be run. # # To do this without source support, we define a dummy function that, when # executed, will load the file (thereby re-defining the function), then # execute that newly-redefined function with the original arguments. # # It's not identical to ksh because ksh apparently does lazy evaluation # and looks for the file to load from only when the function is referenced. # This one requires that the file exist when the function is declared as # `autoload'. # # usage: autoload func [func...] # # The first cut of this was by Bill Trost, trost@reed.bitnet # # Chet Ramey # chet@ins.CWRU.Edu # # Declare a function ($1) to be autoloaded from a file ($2) when it is first # called. This defines a `temporary' function that will `.' the file # containg the real function definition, then execute that new definition with # the arguments given to this `fake' function. The autoload function defined # by the file and the file itself *must* be named identically. # aload() { echo $1 \(\) \{ . $2 \; $1 \"\$\@\" \} > /tmp/au.$$ . /tmp/au.$$ rm /tmp/au.$$ } # # Search $FPATH for a file the same name as the function given as $1, and # autoload the function from that file. There is no default $FPATH. # autoload() { # # save the list of functions; we're going to blow away the arguments # in a second # local args="$*" if [ $# -eq 0 ] ; then echo "usage: autoload function [function...]" return 1 fi # # If there is no $FPATH, there is no work to be done # if [ -z "$FPATH" ] ; then echo autoload: FPATH not set return 1 fi # # This treats FPATH exactly like PATH: a null field anywhere in the # FPATH is treated the same as the current directory. # # The path splitting command is taken from Kernighan and Pike # fp=$(echo $FPATH | sed 's/^:/.:/ s/::/:.:/g s/:$/:./ s/:/ /g') for FUNC in $args ; do # # We're blowing away the arguments to autoload here... # set $fp while [ $# -ne 0 ] ; do if [ -f $1/$FUNC ] ; then break # found it! fi shift done if [ $# -eq 0 ] ; then echo "$FUNC: autoload function not found" continue fi # echo auto-loading $FUNC from $1/$FUNC aload $FUNC $1/$FUNC done return 0 } -- Chet Ramey Network Services Group "Where's my froggie?" Case Western Reserve University chet@ins.CWRU.Edu
bfox@sbphy.ai.mit.edu (Brian Fox) (01/05/90)
Date: 7 Dec 89 17:18:52 GMT From: sun-barr!newstop!texsun!convex!tchrist%convex.COM@ames.arc.nasa.gov (Tom Christiansen) Organization: CONVEX Software Development, Richardson, TX References: <8912030428.AA01426@kailand.kai.com> Sender: bug-bash-request@prep.ai.mit.edu In article <8912030428.AA01426@kailand.kai.com> pwolfe@kailand.kai.com (Patrick Wolfe) writes: >I would like to commend all those who've been working on bash and readline so >far. I plan to continue using bash, and to try to find and fix any bugs I can. >The "vi mode" simply blows away TCSH. Well, it's nice, but it's not as complete a vi as ksh's vi mode, which is too bad. It would be more helpful to tell us what features are missing in Bash. Then perhaps we could put them in. I also like the way tcsh allows ^W to back up to things like / and +, not just to white space. The command <backward-kill-word> operates in this fashion. You can set C-w to run this command in your ~/.inputrc file with: C-w: backward-kill-word And I miss the asynchronous notification of tcsh and csh that's also lacking in ksh. Try putting "notify=" in your ~/.bashrc file. Brian