wtoomey@gara.une.oz (Warren Toomey) (06/01/89)
Here is the second official patch to Clam. For those who missed, Clam is a Tcsh-like shell with command line editing, history, aliases etc. Callum (the author) is starting to attack the code again, and has removed several small bugs. Most notably, he has sprinkled many free()s around the code, so Clam will now not crash after about 100-200 commands. He is also currently rewriting parts of the UCB job control, and terminal control, so these patches won't work too well on UCB machines; it does work well on Minix, and as the original copyright notice says, you shouldn't be running Clam under anything but Minix ! The following postings consist of several context diffs on the Clam files, and where the diff is very big, the file is included instead. Please apply them to your source, as I will base the next patches on this version. Thanks for all those people who have sent in bugs & bug patches for Clam! Before I forget, in part 1 a crc of the main files in Clam is given. Cheers all! Warren Toomey
wtoomey@gara.une.oz (Warren Toomey) (06/01/89)
# This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # CRCLIST builtin.cdif clex.cdif echo x - CRCLIST cat > "CRCLIST" << '//E*O*F CRCLIST//' 57497 4917 alias.c 29568 27856 builtin.c 50076 18172 clex.c 41126 18739 comlined.c 15958 3449 cx.c 34060 189 dotclamr 60211 278 dotlogin 58306 16755 exec.c 53894 977 file.c 02377 1132 global.c 19850 8673 hash.c 60345 7427 header.h 18466 4529 hist.c 34831 10067 job.c 42195 21184 main.c 58968 2660 makefile 53495 26347 meta.c 26813 9392 parse.c 07214 11738 var.c //E*O*F CRCLIST// echo x - builtin.cdif cat > "builtin.cdif" << '//E*O*F builtin.cdif//' *** ../Patch1/builtin.c Thu Jun 1 17:01:14 1989 --- builtin.c Thu Jun 1 16:53:15 1989 *************** *** 57,62 # endif #endif else write(2,"Can't get cwd properly\n",23); } static --- 57,63 ----- # endif #endif else write(2,"Can't get cwd properly\n",23); + free(argv[1]); /* just in case? */ } static *************** *** 66,71 bool appnd,bckgnd; { extern void setdown(); extern int fromfile,isanum(); if (argc>2 || (!isanum(argv[1]) && argc!=1)) --- 67,73 ----- bool appnd,bckgnd; { extern void setdown(); + extern bool loginsh; extern int fromfile,isanum(); void logout(); /* just down from here... */ *************** *** 67,72 { extern void setdown(); extern int fromfile,isanum(); if (argc>2 || (!isanum(argv[1]) && argc!=1)) { --- 69,75 ----- extern void setdown(); extern bool loginsh; extern int fromfile,isanum(); + void logout(); /* just down from here... */ if (loginsh==TRUE) logout(argc,argv,infd,outfd,errfd,ifil,ofil,efil,appnd,bckgnd); *************** *** 68,73 extern void setdown(); extern int fromfile,isanum(); if (argc>2 || (!isanum(argv[1]) && argc!=1)) { write(2,"Bad argument to exit.\n",22); --- 71,78 ----- extern int fromfile,isanum(); void logout(); /* just down from here... */ + if (loginsh==TRUE) + logout(argc,argv,infd,outfd,errfd,ifil,ofil,efil,appnd,bckgnd); if (argc>2 || (!isanum(argv[1]) && argc!=1)) { write(2,"Bad argument to exit.\n",22); *************** *** 645,650 { extern void joblist(); joblist(); } --- 650,656 ----- { extern void joblist(); + /* Have -i or -l flag which gives more info. (stuff in job struct) */ joblist(); } *************** *** 759,765 int pid,i; signal(SIGCHLD,SIG_IGN); /* so that checkjobs doesn't update */ - setexec(); /* set the signal-sending keys */ if (argc==1) { #ifdef DEBUG --- 765,770 ----- int pid,i; signal(SIGCHLD,SIG_IGN); /* so that checkjobs doesn't update */ if (argc==1) { #ifdef DEBUG *************** *** 768,774 if (currentjob) { pid=currentjob->pid; /* current job */ ! if (setpgrp(pid,getpgrp(0))==-1) /* set process group to the shell's */ { write(2,"Can't fg this pid\n",18); return; --- 773,779 ----- if (currentjob) { pid=currentjob->pid; /* current job */ ! if (pid!=getpgrp(pid)) { fprintf(stderr,"Can't bring pid:%d to the foreground. Impossible?\n",pid); fflush(stderr); *************** *** 770,775 pid=currentjob->pid; /* current job */ if (setpgrp(pid,getpgrp(0))==-1) /* set process group to the shell's */ { write(2,"Can't fg this pid\n",18); return; } --- 775,791 ----- pid=currentjob->pid; /* current job */ if (pid!=getpgrp(pid)) { + fprintf(stderr,"Can't bring pid:%d to the foreground. Impossible?\n",pid); + fflush(stderr); + return; + } + #ifdef DEBUG + fprintf(stderr,"setting terminal pg to %d\n",pid); + #endif + if (ioctl(0,TIOCSPGRP,&pid)) perror("fg spg"); + setdown(); + /*if (setpgrp(pid,getpgrp(0))==-1) /* set process group to the shell's + { write(2,"Can't fg this pid\n",18); return; } *** This is wrong. All are in their own process group now */ *************** *** 772,778 { write(2,"Can't fg this pid\n",18); return; ! } c=vget("cwd"); if (strcmp(currentjob->dir,c)) /* if directory has changed */ fprintf(stderr,"[%d] %d %s (wd now: %s)\n",currentjob->jobnumber,currentjob->pid,currentjob->name,currentjob->dir); --- 788,794 ----- { write(2,"Can't fg this pid\n",18); return; ! } *** This is wrong. All are in their own process group now */ c=vget("cwd"); if (strcmp(currentjob->dir,c)) /* if directory has changed */ fprintf(stderr,"[%d] %d %s (wd now: %s)\n",currentjob->jobnumber,currentjob->pid,currentjob->name,currentjob->dir); *************** *** 781,788 fflush(stderr); update(pid,0); /* clear status */ newcurr(); /* change current job to this one (with luck) */ ! kill(pid,SIGCONT); ! (void) waitfor(pid); /* do the waiting here. */ return; } else --- 797,807 ----- fflush(stderr); update(pid,0); /* clear status */ newcurr(); /* change current job to this one (with luck) */ ! #ifdef DEBUG ! fprintf(stderr,"sending CONT to %d grp\n",pid); ! #endif ! if (killpg(pid,SIGCONT)) perror("killpg"); ! else (void) waitfor(pid); /* do the waiting here. */ return; } else *************** *** 812,818 #ifdef DEBUG fprintf(stderr,"fg-ing %d\n",pid); #endif ! if (setpgrp(pid,getpgrp(0))==-1) /* set process group to the shell's */ { write(2,"Can't fg this pid\n",18); return; --- 831,837 ----- #ifdef DEBUG fprintf(stderr,"fg-ing %d\n",pid); #endif ! if (pid!=getpgrp(pid)) { fprintf(stderr,"Can't bring pid:%d to the foreground.\n",pid); fflush(stderr); *************** *** 814,819 #endif if (setpgrp(pid,getpgrp(0))==-1) /* set process group to the shell's */ { write(2,"Can't fg this pid\n",18); return; } --- 833,845 ----- #endif if (pid!=getpgrp(pid)) { + fprintf(stderr,"Can't bring pid:%d to the foreground.\n",pid); + fflush(stderr); + continue; + } + setexec(pid); /* + /*if (setpgrp(pid,getpgrp(0))==-1) /* set process group to the shell's + { write(2,"Can't fg this pid\n",18); return; } *** This is wrong. All things are in their own group now */ *************** *** 816,822 { write(2,"Can't fg this pid\n",18); return; ! } ptr=findjob(pid); c=vget("cwd"); if (strcmp(ptr->dir,c)) /* if directory has changed */ --- 842,848 ----- { write(2,"Can't fg this pid\n",18); return; ! } *** This is wrong. All things are in their own group now */ ptr=findjob(pid); c=vget("cwd"); if (strcmp(ptr->dir,c)) /* if directory has changed */ *************** *** 826,833 fflush(stderr); update(pid,0); /* clear status */ newcurr(); /* change current job to this one (with luck) */ ! kill(pid,SIGCONT); ! (void) waitfor(pid); /* do the waiting here. */ } } --- 852,862 ----- fflush(stderr); update(pid,0); /* clear status */ newcurr(); /* change current job to this one (with luck) */ ! #ifdef DEBUG ! fprintf(stderr,"sending CONT to %d pg\n",pid); ! #endif ! if (killpg(pid,SIGCONT)) perror("killpg"); ! else (void) waitfor(pid); /* do the waiting here. */ } } *************** *** 848,854 if (currentjob) { pid=currentjob->pid; /* current job */ ! if (setpgrp(pid,pid)==-1) { write(2,"Can't bg this pid\n",18); return; --- 877,883 ----- if (currentjob) { pid=currentjob->pid; /* current job */ ! /*if (setpgrp(pid,pid)==-1) { write(2,"Can't bg this pid\n",18); return; *************** *** 852,858 { write(2,"Can't bg this pid\n",18); return; ! } fprintf(stderr,"[%d] %d %s\n",currentjob->jobnumber,currentjob->pid,currentjob->name); fflush(stderr); update(pid,0); /* clear status */ --- 881,887 ----- { write(2,"Can't bg this pid\n",18); return; ! } *** Don't need this, already done now */ fprintf(stderr,"[%d] %d %s\n",currentjob->jobnumber,currentjob->pid,currentjob->name); fflush(stderr); update(pid,0); /* clear status */ *************** *** 857,863 fflush(stderr); update(pid,0); /* clear status */ newcurr(); /* change current job to this one (with luck) */ ! kill(pid,SIGCONT); } else { --- 886,895 ----- fflush(stderr); update(pid,0); /* clear status */ newcurr(); /* change current job to this one (with luck) */ ! #ifdef DEBUG ! fprintf(stderr,"killpg on pid %d\n",pid); ! #endif ! if (killpg(pid,SIGCONT)) perror("killpg"); } else { *************** *** 883,889 if (!isanum(c)) continue; pid=atoi(c); } ! if (setpgrp(pid,pid)==-1) { write(2,"Can't bg this pid\n",18); return; --- 915,921 ----- if (!isanum(c)) continue; pid=atoi(c); } ! /*if (setpgrp(pid,pid)==-1) { write(2,"Can't bg this pid\n",18); return; *************** *** 887,893 { write(2,"Can't bg this pid\n",18); return; ! } ptr=findjob(pid); fprintf(stderr,"[%d] %d %s\n",ptr->jobnumber,ptr->pid,ptr->name); fflush(stderr); --- 919,925 ----- { write(2,"Can't bg this pid\n",18); return; ! } *** Don't need this, now, already done */ ptr=findjob(pid); fprintf(stderr,"[%d] %d %s\n",ptr->jobnumber,ptr->pid,ptr->name); fflush(stderr); *************** *** 893,899 fflush(stderr); update(pid,0); /* clear status */ newcurr(); /* change current job to this one (with luck) */ ! kill(pid,SIGCONT); } } --- 925,931 ----- fflush(stderr); update(pid,0); /* clear status */ newcurr(); /* change current job to this one (with luck) */ ! if (killpg(pid,SIGCONT)) perror("killpg"); } } //E*O*F builtin.cdif// echo x - clex.cdif cat > "clex.cdif" << '//E*O*F clex.cdif//' *** ../Patch1/clex.c Thu Jun 1 17:01:44 1989 --- clex.c Thu Jun 1 16:53:46 1989 *************** *** 129,135 int i=0,max,looping=1,bltin; char c; - buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat))); yankprev(line,*pos,word); /* first get the thing we're trying to expand */ /* Look for a slash to see if its a relative path name or current directory. --- 129,134 ----- int i=0,max,looping=1,bltin; char c; yankprev(line,*pos,word); /* first get the thing we're trying to expand */ /* Look for a slash to see if its a relative path name or current directory. *************** *** 205,210 } max=strlen(&word[i+1]); start=0; while ((entry=readdir(dd))!=NULL) /* Check to see if the chars we typed match so far */ if (!strncmp(&word[i+1],entry->d_name,max)) --- 204,210 ----- } max=strlen(&word[i+1]); start=0; + buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat))); while ((entry=readdir(dd))!=NULL) /* Check to see if the chars we typed match so far */ if (!strncmp(&word[i+1],entry->d_name,max)) *************** *** 227,232 else ptr->c_isdir=FALSE; } closedir(dd); } } else /* no slash */ --- 227,233 ----- else ptr->c_isdir=FALSE; } closedir(dd); + free(buf); } } else /* no slash */ *************** *** 239,244 printf("\n%sCan't open %s\n",beep,PASSWD); prprompt(1); show(line,curs,TRUE); } for (i=0;word[i];i++) word[i]=word[i+1]; --- 240,246 ----- printf("\n%sCan't open %s\n",beep,PASSWD); prprompt(1); show(line,curs,TRUE); + return; } for (i=0;word[i];i++) word[i]=word[i+1]; *************** *** 318,323 } if (t!=WORD) continue; /* illegal path component ignored */ if ((dd=opendir(dir))==NULL) continue; /* same again */ while ((entry=readdir(dd))!=NULL) /* Check to see if the chars we typed match so far */ if (!strncmp(word,entry->d_name,max)) --- 320,326 ----- } if (t!=WORD) continue; /* illegal path component ignored */ if ((dd=opendir(dir))==NULL) continue; /* same again */ + buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat))); while ((entry=readdir(dd))!=NULL) /* Check to see if the chars we typed match so far */ if (!strncmp(word,entry->d_name,max)) *************** *** 340,345 else ptr->c_isdir=FALSE; } closedir(dd); } /* end while retsym*/ } /* end else ~ */ } /* end else findslash */ --- 343,349 ----- else ptr->c_isdir=FALSE; } closedir(dd); + free(buf); } /* end while retsym*/ } /* end else ~ */ } /* end else findslash */ *************** *** 416,422 int i,bltin,max,index=0,maxlength=0,temp,compare(); extern int beeplength; - buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat))); if ((pos==0) || (line[pos-1]==' ')) strcpy(word,""); /* nothing there to get */ else --- 420,425 ----- int i,bltin,max,index=0,maxlength=0,temp,compare(); extern int beeplength; if ((pos==0) || (line[pos-1]==' ')) strcpy(word,""); /* nothing there to get */ else *************** *** 488,493 show(line,curs,TRUE); return; } while ((entry=readdir(dd))!=NULL) { if (entry->d_name[0]=='.' && (entry->d_name[1]=='.' || entry->d_name[1]==EOS)) --- 491,497 ----- show(line,curs,TRUE); return; } + buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat))); while ((entry=readdir(dd))!=NULL) { if (entry->d_name[0]=='.' && (entry->d_name[1]=='.' || entry->d_name[1]==EOS)) *************** *** 512,517 } } closedir(dd); } } else /* no slash */ --- 516,522 ----- } } closedir(dd); + free(buf); } } else /* no slash */ //E*O*F clex.cdif// exit 0
wtoomey@gara.une.oz (Warren Toomey) (06/01/89)
# This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # comlined.c echo x - comlined.c cat > "comlined.c" << '//E*O*F comlined.c//' /****************************************************************************** ** ** ** comlined.c ** ** This file contains the COMmand LINe EDitor. ** ** ** ******************************************************************************/ #include "header.h" /* Minix seems to have a strange stdio.h FILE struct */ #ifdef MINIX #define _file _fd #endif extern char termcapbuf[]; extern FILE *zin,*zout,*fopen(); #ifndef ATARI_ST void mputc(c,f,curs) char c; FILE *f; int curs[]; { extern int wid; write(f->_file,&c,1); curs[0]++; if (curs[0]>=wid) { write(f->_file,"\n",1); /* goto start of next line */ curs[0]=curs[0]%wid; /* hopefully gives zero */ curs[1]++; } } #else void mputc(c,f,curs) int c; FILE *f; int curs[]; { extern int wid; char cc = c; write(f->_file,&cc,1); curs[0]++; if (curs[0]>=wid) { write(f->_file,"\n",1); /* goto start of next line */ curs[0]=curs[0]%wid; /* hopefully gives zero */ curs[1]++; } } #endif #ifndef ATARI_ST void oputc(c) char c; { write(zout->_file,&c,1); } #else int oputc(c) int c; { char cc = c; return write(zout->_file,&cc,1); } #endif void go(curs,hor,vert) int curs[],hor,vert; { extern char bs[],nd[],up[]; int hdiff,vdiff; vdiff=vert-curs[1]; /* vertical difference between */ /* current and future positions */ if (vdiff<=0) /* if negative go up */ for(;vdiff;vdiff++) tputs(up,1,oputc); else /* else go down */ { for(;vdiff;vdiff--) write(1,"\n",1); curs[0]=0; } hdiff=hor-curs[0]; /* horizontal difference between */ /* current and future positions */ curs[0]=hor; curs[1]=vert; /* a new current pos, hopefully */ /* assigned here because hor changed below and curs needed above */ if (hdiff<0) /* if negative go back */ if (-hdiff<=hor) /* if shorter distance just use ^H */ for(;hdiff;hdiff++) write(zout->_file,bs,strlen(bs)); else /* else cr and go forward */ { write(zout->_file,"\r",1); for (;hor;hor--) tputs(nd,1,oputc); } else /* have to go forward */ for (;hdiff;hdiff--) tputs(nd,1,oputc); } void backward(curs) int curs[]; { extern int wid; extern char bs[]; if (curs[0]==0) go(curs,wid-1,curs[1]-1); else { write(zout->_file,bs,strlen(bs)); curs[0]--; } } void forward(curs) int curs[]; { extern int wid; extern char nd[]; curs[0]++; if (curs[0]>=wid) { write(zout->_file,"\n",1); /* goto start of next line */ curs[0]=curs[0]%wid; /* hopefully gives zero */ curs[1]++; } else tputs(nd,1,oputc); } void clrscrn() { extern char cl[]; tputs(cl,1,oputc); /* clear the screen */ } void insert(line,pos,letter,curs) char *line,letter; int pos,curs[]; { extern int wid; int i,horig,vorig; char c; for (i=pos;line[i];i++); /* goto end of line */ for (;i!=pos;i--) line[i]=line[i-1]; /* copy characters forward */ line[pos]=letter; /* insert new char */ if (letter<32) horig=curs[0]+2; else horig=curs[0]+1; vorig=curs[1]; if (horig>wid-1) { horig=horig%wid; vorig++; } for (c=line[pos];c;c=line[++pos]) /* write out rest of line */ { if (c<32) /* if it's a control char */ { mputc('^',zout,curs); /* print out the ^ and */ mputc(c+64,zout,curs); /* the equivalent char for it*/ } else mputc(c,zout,curs); } go(curs,horig,vorig); } #ifdef __STDC__ void show(char *line, int *curs, bool clearing) #else void show(line,curs,clearing) char *line; int curs[]; bool clearing; #endif { extern int lenprompt; int pos=0,horig,vorig; char c; horig=curs[0];vorig=curs[1]; /* save original values */ if (clearing==TRUE) { curs[0]=lenprompt;curs[1]=0; } else { go(curs,lenprompt,0); /* goto start of line */ } for (c=line[pos];c!=EOS;c=line[++pos]) /* write out rest of line */ if (c<32) /* if it's a control char */ { mputc('^',zout,curs); /* print out the ^ and */ mputc(c+64,zout,curs); /* the equivalent char for it*/ } else mputc(c,zout,curs); go(curs,horig,vorig); /* go back from whence you came */ } void goend(line,pos,curs) char *line; int *pos,curs[]; { char c; for (c=line[*pos];c;c=line[++(*pos)]) { if (c<32) { mputc('^',zout,curs); mputc(c+64,zout,curs); } else mputc(c,zout,curs); } } void copyback(line,pos,curs,count) char *line; int pos,curs[],count; { char c; int i,horig,vorig,wipe; #ifdef DEBUG fprintf(stderr,"pos %d count %d\n",pos,count); #endif if ((i=pos+count)<MAXLL) { wipe=0; for (;line[i]!=EOS;++i) /* copy line back count chars */ line[i-count]=line[i]; for (horig=i-count;i>horig && i<MAXLL+1;i--) { if (line[i-count]<32) wipe+=2; /* tally how much we need to wipe */ else wipe++; line[i-1]=EOS; /* end with nulls */ } } else { write(2,"count passed to copyback is too big\n",35); return; } horig=curs[0];vorig=curs[1]; for (c=line[pos];c;c=line[++pos]) if (c<32) { mputc('^',zout,curs); mputc(c+64,zout,curs); } else mputc(c,zout,curs); #ifdef DEBUG fprintf(stderr,"wipe %d\n",wipe); #endif for (i=0;i<wipe;i++) mputc(' ',zout,curs); /* blank old chars */ go(curs,horig,vorig); } void delnextword(line,pos,curs) char *line; int pos,curs[]; { int inword=0,l=1,charcount=0; while(l) switch(line[pos+charcount]) { case EOS: l=0; break; case ' ':case '\t':case '>':case '<':case '|': case ';':case '=':case '+':case '&':case '`': if (inword) l=0; else charcount++; break; default: inword=1; charcount++; } #ifdef DEBUG fprintf(stderr,"Deleting %d chars\n",charcount); #endif copyback(line,pos,curs,charcount); } void delprevword(line,pos,curs) char *line; int *pos,curs[]; { int inword=0,l=1,charcount=0; char c; while(l) if ((*pos)>0) switch (c=line[(*pos)-1]) { case ' ':case '\t':case '<':case '>':case '|': case ';':case '=':case '+':case '&':case '`': if (inword) l=0; else { charcount++; (*pos)--; } break; default: inword=1; charcount++; (*pos)--; } else l=0; #ifdef DEBUG fprintf(stderr,"Deleting %d chars\n",charcount); #endif /* l should be zero already, aren't I naughty! */ for (;l<charcount;l++) backward(curs); /* move back */ copyback(line,*pos,curs,charcount); /* and copy the line on top */ } void backword(line,pos,curs) char *line; int *pos,curs[]; { int inword=0,l=1; char c; while(l) if ((*pos)>0) switch (c=line[(*pos)-1]) { case ' ':case '\t':case '<':case '>':case '|': case ';':case '=':case '+':case '&':case '`': if (inword) l=0; else { backward(curs); (*pos)--; } break; default: inword=1; if (c<32) backward(curs); backward(curs); (*pos)--; } else l=0; } void forword(line,pos,curs) char *line; int *pos,curs[]; { int inspace=0,l=1; char c; while(l) switch (c=line[*pos]) { case EOS: l=0; break; case ' ':case '\t':case '<':case '>':case '|': case ';':case '=':case '+':case '&':case '`': inspace=1; forward(curs); (*pos)++; break; default: if (inspace) l=0; else { if (c<32) forward(curs); forward(curs); (*pos)++; } } } void yanknext(line,pos,yankbuf) char *line,*yankbuf; int pos; { int l=1,inword=0,i=0; while(l) switch(line[pos]) { case EOS: l=0; yankbuf[i]=EOS; break; case ' ':case '\t':case '<':case '>':case '|': case ';':case '=':case '+':case '&':case '`': if (inword) { l=0; yankbuf[i]=EOS; } else yankbuf[i++]=line[pos++]; break; default: inword=1; yankbuf[i++]=line[pos++]; } } void yankprev(line,pos,yankbuf) char *line,*yankbuf; int pos; { int stpos=pos,inword=0,l=1; while(l && stpos>0) /* this loop finds the start of the */ switch(line[stpos-1]) /* previous word (at stpos) */ { case ' ':case '\t':case '>':case '<':case '|':case '"': case ';':case '=':case '+':case '&':case '`':case '\'': if (inword) l=0; else stpos--; break; default: inword=1; stpos--; } for (l=0;stpos<pos;stpos++,l++) /* then copy from stpos upto pos */ yankbuf[l]=line[stpos]; yankbuf[l]=EOS; } void clrline(line,pos,curs) char *line; int pos,curs[]; { extern bool tflagexist(); extern char cd[]; int i,horig,vorig; if (tflagexist("cd",termcapbuf)==TRUE) /* If there's a special char for clr */ { /* then use it */ tputs(cd,1,oputc); for (i=pos;line[i];i++) line[i]=EOS; } else /* else we gotta use spaces. */ { horig=curs[0];vorig=curs[1]; /* Orginal values for curs set. */ for (i=pos;line[i];i++) /* Wipe out all those chars */ { /* with spaces (so slow), */ mputc(' ',zout,curs); if (line[i]<32) mputc(' ',zout,curs); line[i]=EOS; } go(curs,horig,vorig); /* restore original curs position */ } } void transpose(line,pos,curs) char *line; int pos,curs[]; { char temp; if (line[pos-1]<32) backward(curs); backward(curs); temp=line[pos]; line[pos]=line[pos-1]; line[pos-1]=temp; if (line[pos-1]<32) { mputc('^',zout,curs); mputc(line[pos-1]+64,zout,curs); } else mputc(line[pos-1],zout,curs); if (line[pos]<32) { mputc('^',zout,curs); mputc(line[pos]+64,zout,curs); } else mputc(line[pos],zout,curs); if (line[pos]<32) backward(curs); backward(curs); } int strip(line) char *line; { int i,nosave=0; for (i=0;line[i]==' ';i++); if (line[i]=='#') { nosave=1; i++; } if (i) strcpy(line,&line[i]); return(nosave); } void tardis(line,pos,curs) char *line; int *pos,curs[]; { extern void loadhist(); extern char beep[]; extern int curr_hist,matchhist(),beeplength; int hnum; /* matchhist finds the history line matching the previous command and returns the one after that, predicting that you want to do the same thing. */ hnum=matchhist(curr_hist-1); if (hnum) loadhist(line,pos,hnum,curs); else write(1,beep,beeplength); } bool getline(line,nosave,feature_off) char *line; int *nosave,feature_off; { extern int curr_hist,maxhist,lenprompt,O_echoline,beeplength; extern char beep[],yankbuf[],*vget(); extern void loadhist(),savehist(),leave_shell(),complete(),nameopt(),prprompt(),help(); char c; int times=1,i,pos=0,hist=curr_hist,curs[2],hsave=lenprompt,vsave=0,possave=0 ,try=0; curs[0]=lenprompt; /*lenprompt global set by prprompt or when prompt set*/ curs[1]=0; /* start on line 0 */ if (vget("TARDIS")!=(char *)UNDEF && !feature_off) tardis(line,&pos,curs); while (1) { c=getc(zin); for (;times>0;times--) switch(c) { case EOF : fprintf(stderr,"Help me, I'm being hit by a looney with a stick.\n"); if (!try) { fprintf(stderr,"Trying to reassign stdin..."); zin=stdin; try=1; continue; } else { fprintf(stderr,"Trying to reopen stdin..."); if ((zin=fopen("/dev/tty","w+"))==NULL) { fprintf(stderr,"failed!\n"); exit(1); } fprintf(stderr,"Successful!\n"); try=0; } continue; case EOS : hsave=curs[0]; /* save position (make mark) */ vsave=curs[1]; possave=pos; break; case 1 : go(curs,lenprompt,0); /* goto start of the line */ pos=0; break; case 2 : if (pos>0) /* if not at home, go back */ { if (line[pos-1]<32) backward(curs); backward(curs); pos--; } else write(1,beep,beeplength); /* else ring bell */ break; case 3 : goend(line,&pos,curs); write(zout->_file,"\n",1); return(FALSE); case 4 : if (line[0]==EOS && !feature_off) leave_shell(); /*eof*/ else if (line[pos]!=EOS) copyback(line,pos,curs,1); /* delete char */ else if (!feature_off) nameopt(line,pos,curs); break; case 5 : goend(line,&pos,curs); /* goto end of the line */ break; case 6 : if (line[pos]!=EOS) /* if not at end, go forward */ { if (line[pos]<32) forward(curs); forward(curs); pos++; } else write(1,beep,beeplength); /* else ring bell */ break; case 7 : pos=0; /* kill the whole line */ go(curs,lenprompt,0); /* goto start */ clrline(line,0,curs); /* and kill from pos=0 */ hist=curr_hist; /* reset hist */ break; case 127: case 8 : if (pos>0) /* if not at home, delete */ { if (line[pos-1]<32) backward(curs); backward(curs); copyback(line,--pos,curs,1); /*move line back on to prev char*/ } else write(1,beep,beeplength); /* else ring bell */ break; case '\t': if (line[0]!=EOS) complete(line,&pos,curs); /* try to complete word */ else write(1,beep,beeplength); break; case '\r': /* end of the line, go and */ case '\n': goend(line,&pos,curs); write(zout->_file,"\n",1); if (feature_off) return(TRUE); *nosave=strip(line); /* process it now */ if (line[0]!=EOS) { if (O_echoline) { write(2,line,strlen(line)); write(2,"\n",1); } return(TRUE); } else return(FALSE); case 11 : clrline(line,pos,curs); /* kill line from cursor on */ break; case 12 : if (feature_off) break; clrscrn(); /* Clear the screen */ prprompt(1); /* Reprint the prompt and */ show(line,curs,TRUE); /* the line typed so far. */ break; case 14 : if (feature_off) break; if (hist<curr_hist) /* put next hist in line buf */ loadhist(line,&pos,++hist,curs); else if (hist==curr_hist) tardis(line,&pos,curs); else write(1,beep,beeplength); break; case 15 : continue; case 16 : if (feature_off) break; if (hist>curr_hist-maxhist && hist>1) /* put prev hist in line buf */ { if (hist==curr_hist) savehist(line,curr_hist,maxhist); loadhist(line,&pos,--hist,curs); } else write(1,beep,beeplength); break; case 17 : continue; case 18 : show(line,curs,FALSE); /* reprint the line */ break; case 19 : continue; case 20 : if (pos>0 && line[pos]!=EOS) /* if not home or at end */ transpose(line,pos,curs); /* swap current and prev char */ else write(1,beep,beeplength); /* else ring bell */ break; case 21 : times=0; c=getc(zin); while(isdigit(c)) { times=times*10+c-48; c=getc(zin); } times++; /* need to add 1 because it's dec'ed */ break; /* immediately at end of for loop */ case 22 : if (pos>=MAXLL) { write(1,beep,beeplength); continue; } mputc('"',zout,curs); backward(curs); /* literal char */ c=getc(zin); if (c) /* don't allow EOS (null) */ insert(line,pos++,c,curs); break; case 23 : if (pos) delprevword(line,&pos,curs); else write(1,beep,beeplength); break; case 24 : pos=possave; go(curs,hsave,vsave); break; case 25 : if (pos!=0) /* if not at home */ yankprev(line,pos,yankbuf); /* yank previous word */ else write(1,beep,beeplength); /* else ring bell */ break; case 26 : continue; case 27 : switch(c=getc(zin)) { case 4 : if (!feature_off) nameopt(line,pos,curs); break; case 0177: case 8 : if (pos>0) { backward(curs); copyback(line,--pos,curs,1); } else write(1,beep,beeplength); break; case 12 : if (feature_off) break; clrscrn(); prprompt(1); show(line,curs,TRUE); break; case 27 : case '\t': if (!feature_off) if (line[0]!=EOS) complete(line,&pos,curs); else write(1,beep,beeplength); break; case 'b' : case 2: case 'B' : if (pos>0) backword(line,&pos,curs); else write(1,beep,beeplength); break; case 'd' : case 'D' : if (line[pos]!=EOS) delnextword(line,pos,curs); else write(1,beep,beeplength); break; case 'f' : case 6: case 'F' : if (line[pos]!=EOS) forword(line,&pos,curs); else write(1,beep,beeplength); break; case 'h' : case 'H' : if (!feature_off) help(line,pos,curs); break; case 'p' : case 'P' : if (pos>MAXLL-strlen(yankbuf)) { write(1,beep,beeplength); break; } for (i=0;yankbuf[i];i++) /* insert yank buffer */ insert(line,pos++,yankbuf[i],curs); break; case 25 : if (pos!=0) /* as above */ yankprev(line,pos,yankbuf); else write(1,beep,beeplength); break; case 'y' : case 'Y' : if (line[pos]!=EOS) /* if not at end */ yanknext(line,pos,yankbuf);/* yank next word */ else write(1,beep,beeplength);/* else ring bell */ break; case 'w' : case 23: case 'W' : if (pos) /* if not at end */ delprevword(line,&pos,curs); else write(1,beep,beeplength); break; case '0':case '1':case '2':case '3':case '4': case '5':case '6':case '7':case '8':case '9': times=0; while(isdigit(c)) { times=times*10+c-48; c=getc(zin); } times++; /* need to add 1 because it's dec'ed */ break; /* immediately at end of for loop */ case '/' : if (line[pos]) /* search forward */ { c=getc(zin); /* char to search for */ for (i=pos+1;line[i] && c!=line[i];i++); if (line[i]) while (pos<i) { pos++; if (line[pos-1]<32) forward(curs); forward(curs); } else write(1,beep,beeplength); /* not found */ } else write(1,beep,beeplength);/* at end of line */ break; case '?' : if (pos>0) /* search backwards */ { c=getc(zin); /* char to search for */ for (i=pos-1;i>=0 && c!=line[i];i--); if (i>=0) while (pos>i) { pos--; if (line[pos]<32) backward(curs); backward(curs); } else write(1,beep,beeplength); /* not found */ } else write(1,beep,beeplength); /* at end of line */ break; default : write(1,beep,beeplength); } break; case 29 : continue; default : if (pos>=MAXLL) { write(1,beep,beeplength); break; } insert(line,pos++,c,curs); break; } times=1; } } //E*O*F comlined.c// exit 0
wtoomey@gara.une.oz (Warren Toomey) (06/01/89)
# This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # exec.cdif global.c hash.cdif header.hdif echo x - exec.cdif cat > "exec.cdif" << '//E*O*F exec.cdif//' *** ../Patch1/exec.c Thu Jun 1 17:02:51 1989 --- exec.c Thu Jun 1 16:54:59 1989 *************** *** 19,25 struct adefn *alias_defn; int stopflg,NoIoctl=0; ! void setexec() { #ifdef ATT struct termio tbuf; --- 19,26 ----- struct adefn *alias_defn; int stopflg,NoIoctl=0; ! void setexec(pid) ! int pid; { #ifdef ATT struct termio tbuf; *************** *** 46,51 fprintf(stderr,"set exec\n"); #endif termod=(struct sgttyb *) malloc ((unsigned)(sizeof(struct sgttyb))); if (ioctl(0,TIOCGETP,termod)) perror("ioctl in setexec"); termod->sg_flags &= (~CBREAK); /* cooked mode */ --- 47,53 ----- fprintf(stderr,"set exec\n"); #endif + /*** All this will be rewritten ***/ termod=(struct sgttyb *) malloc ((unsigned)(sizeof(struct sgttyb))); if (ioctl(0,TIOCGETP,termod)) perror("ioctl in setexec"); termod->sg_flags &= (~CBREAK); /* cooked mode */ *************** *** 51,56 termod->sg_flags &= (~CBREAK); /* cooked mode */ termod->sg_flags |= ECHO; /* with echo */ if (ioctl(0,TIOCSETN,termod)) perror("ioctl"); setsigc=(struct tchars *) malloc ((unsigned)(sizeof(struct tchars))); if (ioctl(0,TIOCGETC,setsigc)) perror("ioctl"); setsigc->t_intrc=03; /* interrupt ctrl c */ --- 53,59 ----- termod->sg_flags &= (~CBREAK); /* cooked mode */ termod->sg_flags |= ECHO; /* with echo */ if (ioctl(0,TIOCSETN,termod)) perror("ioctl"); + free(termod); setsigc=(struct tchars *) malloc ((unsigned)(sizeof(struct tchars))); if (ioctl(0,TIOCGETC,setsigc)) perror("ioctl"); setsigc->t_intrc=03; /* interrupt ctrl c */ *************** *** 57,62 setsigc->t_quitc=034; /* quit ctrl \ */ setsigc->t_eofc=04; /* eof ctrl d */ if (ioctl(0,TIOCSETC,setsigc)) perror("ioctl"); # ifndef MINIX moresigc.t_suspc=032; /* suspend ctrl z */ moresigc.t_dsuspc=031; /* delayed suspend ctrl y */ --- 60,66 ----- setsigc->t_quitc=034; /* quit ctrl \ */ setsigc->t_eofc=04; /* eof ctrl d */ if (ioctl(0,TIOCSETC,setsigc)) perror("ioctl"); + free(setsigc); # ifndef MINIX moresigc.t_suspc=032; /* suspend ctrl z */ moresigc.t_dsuspc=031; /* delayed suspend ctrl y */ *************** *** 65,70 moresigc.t_werasc=027; /* word erase ctrl w */ moresigc.t_lnextc=026; /* literal next char ctrl v */ if (ioctl(0,TIOCSLTC,&moresigc)) perror("ioctl"); # endif #endif --- 69,86 ----- moresigc.t_werasc=027; /* word erase ctrl w */ moresigc.t_lnextc=026; /* literal next char ctrl v */ if (ioctl(0,TIOCSLTC,&moresigc)) perror("ioctl"); + if (pid) /* this is so when setexec is called without pid just to set the + signal keys, it doesn't repeat this bit (if that ever happens). */ + { + if (ioctl(0,TIOCSPGRP,&pid)) perror("ioctl spg"); + #ifdef DEBUG + if (ioctl(0,TIOCGPGRP,&pid)) perror("Dioctl"); + fprintf(stderr,"terminal's pgrp is %d\n",pid); + fprintf(stderr,"Setting pgrp to %d\n",pid); + #endif + if (setpgrp(pid,pid)) perror("setpgrp"); + signal(SIGTTIN,SIG_DFL); + } # endif /*** end of rewrite ***/ *************** *** 66,71 moresigc.t_lnextc=026; /* literal next char ctrl v */ if (ioctl(0,TIOCSLTC,&moresigc)) perror("ioctl"); # endif #endif --- 82,88 ----- signal(SIGTTIN,SIG_DFL); } # endif + /*** end of rewrite ***/ #endif *************** *** 76,81 #ifndef MINIX int pid; pid=getpid(); setpgrp(pid,pid); signal(SIGTTIN,SIG_DFL); --- 93,101 ----- #ifndef MINIX int pid; + #ifdef DEBUG + fprintf(stderr,"setbgexec\n"); + #endif pid=getpid(); setpgrp(pid,pid); signal(SIGTTIN,SIG_DFL); *************** *** 176,185 { if (stopflg) break; retval=0; - #if 0 - /* WAS: same problem here as in main.c:fopen() */ - act=intercom(line,&pos,&pid,FALSE,NULL,fromfile); - #else act=intercom(line,&pos,&pid, &i, FALSE,fromfile); #endif --- 196,201 ----- { if (stopflg) break; retval=0; act=intercom(line,&pos,&pid, &i, FALSE,fromfile); #ifdef DEBUG *************** *** 181,187 act=intercom(line,&pos,&pid,FALSE,NULL,fromfile); #else act=intercom(line,&pos,&pid, &i, FALSE,fromfile); - #endif #ifdef DEBUG fprintf(stderr,"pid returned from intercom is %d for line %s\n",pid,line); --- 197,202 ----- if (stopflg) break; retval=0; act=intercom(line,&pos,&pid, &i, FALSE,fromfile); #ifdef DEBUG fprintf(stderr,"pid returned from intercom is %d for line %s\n",pid,line); *************** *** 187,195 fprintf(stderr,"pid returned from intercom is %d for line %s\n",pid,line); fprintf(stderr,"fileno(zin) is %d\n",fileno(zin)); #endif - #if 0 - for (i=3;i<=20;i++) if (i!=fileno(zin)) close(i); - #else for (i=3;i<=NFILES;i++) if (i!=fileno(zin)) close(i); #endif if (pid && act!=BCKGND) --- 202,207 ----- fprintf(stderr,"pid returned from intercom is %d for line %s\n",pid,line); fprintf(stderr,"fileno(zin) is %d\n",fileno(zin)); #endif for (i=3;i<=NFILES;i++) if (i!=fileno(zin)) close(i); if (pid && act!=BCKGND) retval=waitfor(pid); *************** *** 191,197 for (i=3;i<=20;i++) if (i!=fileno(zin)) close(i); #else for (i=3;i<=NFILES;i++) if (i!=fileno(zin)) close(i); - #endif if (pid && act!=BCKGND) retval=waitfor(pid); #ifndef MINIX --- 203,208 ----- fprintf(stderr,"fileno(zin) is %d\n",fileno(zin)); #endif for (i=3;i<=NFILES;i++) if (i!=fileno(zin)) close(i); if (pid && act!=BCKGND) retval=waitfor(pid); #ifndef MINIX *************** *** 552,560 #endif } } - #if 0 - for (fd=3;fd<20;fd++) - #else for (fd=3;fd<NFILES;fd++) #endif (void) close(fd); --- 563,568 ----- #endif } } for (fd=3;fd<NFILES;fd++) (void) close(fd); } *************** *** 556,563 for (fd=3;fd<20;fd++) #else for (fd=3;fd<NFILES;fd++) ! #endif ! (void) close(fd); } #ifdef __STDC__ --- 564,570 ----- } } for (fd=3;fd<NFILES;fd++) ! (void) close(fd); } #ifdef __STDC__ *************** *** 622,629 fprintf(stderr,"bckgnd %d piped %d\n",bckgnd,piped); fprintf(stderr,"maybe setexec from execute\n"); #endif ! if (bckgnd==TRUE) setbgexec(); ! else if (!NoIoctl && piped==FALSE && !fromfile) setexec(); redirect(infd,outfd,errfd,ifil,ofil,efil,appnd,bckgnd); if (alias_defn!=0) { --- 629,636 ----- fprintf(stderr,"bckgnd %d piped %d\n",bckgnd,piped); fprintf(stderr,"maybe setexec from execute\n"); #endif ! /*if (bckgnd==TRUE) setbgexec(); ! else*/ if (!NoIoctl && piped==FALSE && !fromfile) setexec(pid=getpid()); redirect(infd,outfd,errfd,ifil,ofil,efil,appnd,bckgnd); if (alias_defn!=0) { *************** *** 654,659 for (i=argc;i;i--) argv[i]=argv[i-1]; argv[1]=(char *) realloc (argv[1],(unsigned)(strlen(path)+1)); strcpy(argv[1],path); /* full path for source file */ argv[0]=(char *) malloc ((unsigned)(strlen(DFLTSH)+1)); strcpy(argv[0],DFLTSH); strcpy(path,DFLTSH); --- 661,669 ----- for (i=argc;i;i--) argv[i]=argv[i-1]; argv[1]=(char *) realloc (argv[1],(unsigned)(strlen(path)+1)); strcpy(argv[1],path); /* full path for source file */ + #ifdef DEBUG + fprintf(stderr,"argv[1] is %s<\n",argv[1]); + #endif argv[0]=(char *) malloc ((unsigned)(strlen(DFLTSH)+1)); strcpy(argv[0],DFLTSH); strcpy(path,DFLTSH); *************** *** 657,663 argv[0]=(char *) malloc ((unsigned)(strlen(DFLTSH)+1)); strcpy(argv[0],DFLTSH); strcpy(path,DFLTSH); ! argc++; /* one more arg for mankind... */ #ifdef DEBUG fprintf(stderr,"path %s argv[0] %s argv[1] %s argv[2] %s\n",path,argv[0],argv[1],argv[2]); #endif --- 667,673 ----- argv[0]=(char *) malloc ((unsigned)(strlen(DFLTSH)+1)); strcpy(argv[0],DFLTSH); strcpy(path,DFLTSH); ! argv[++argc]=NULL; /* one more arg for mankind... */ #ifdef DEBUG fprintf(stderr,"path %s argv[0] %s argv[1] %s argv[2] %s\n",path,argv[0],argv[1],argv[2]); #endif //E*O*F exec.cdif// echo x - global.c cat > "global.c" << '//E*O*F global.c//' /****************************************************************************** ** ** ** global.c ** ** Some global declarations for the entire program. ** ** ** ******************************************************************************/ #include "header.h" char termcapbuf[1024],bs[10],nd[10],cl[10],cd[10],up[10],so[10],se[10],beep[20],yankbuf[256],*invokename,**arguments,*current_alias,*newenv[MAXARG]; FILE *zin,*zout,*fopen(); int lenprompt,curr_hist,maxhist=0,wid,h_hits,h_misses,hits,misses,beeplength,fromfile,disable_auto,numargs,jobdone,globpid; int O_execstring=0,O_exiterror=0,O_faststart=0,O_interact,O_noexec=0,O_echoline=0,O_echoexp=0,O_echobefore=0,O_echoexpbefore=0; bool hashed,loginsh; /* Clam terminal driver characteristics which must always be set for Clam. */ struct sgttyb clam_sgttyb; struct tchars clam_tchars; #ifndef MINIX struct ltchars clam_ltchars; #endif //E*O*F global.c// echo x - hash.cdif cat > "hash.cdif" << '//E*O*F hash.cdif//' *** ../Patch1/hash.c Thu Jun 1 17:03:06 1989 --- hash.c Thu Jun 1 16:55:14 1989 *************** *** 31,37 char *dir,*entname; int nojoin; { ! struct stat *buf; char fpn[MAXWL]; buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat))); --- 31,37 ----- char *dir,*entname; int nojoin; { ! struct stat buf; char fpn[MAXWL]; if (nojoin) *************** *** 34,40 struct stat *buf; char fpn[MAXWL]; - buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat))); if (nojoin) stat(dir,buf); else --- 34,39 ----- struct stat buf; char fpn[MAXWL]; if (nojoin) stat(dir,&buf); else *************** *** 36,42 buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat))); if (nojoin) ! stat(dir,buf); else { sprintf(fpn,"%s/%s",dir,entname); --- 35,41 ----- char fpn[MAXWL]; if (nojoin) ! stat(dir,&buf); else { sprintf(fpn,"%s/%s",dir,entname); *************** *** 40,46 else { sprintf(fpn,"%s/%s",dir,entname); ! stat(fpn,buf); } if (((buf->st_mode & S_IFMT)==S_IFREG) && (buf->st_mode & 0111)) return(TRUE); return(FALSE); --- 39,45 ----- else { sprintf(fpn,"%s/%s",dir,entname); ! stat(fpn,&buf); } if (((buf.st_mode & S_IFMT)==S_IFREG) && (buf.st_mode & 0111)) return(TRUE); *************** *** 42,48 sprintf(fpn,"%s/%s",dir,entname); stat(fpn,buf); } ! if (((buf->st_mode & S_IFMT)==S_IFREG) && (buf->st_mode & 0111)) return(TRUE); return(FALSE); } --- 41,48 ----- sprintf(fpn,"%s/%s",dir,entname); stat(fpn,&buf); } ! if (((buf.st_mode & S_IFMT)==S_IFREG) && (buf.st_mode & 0111)) ! return(TRUE); return(FALSE); } *************** *** 196,201 return; } strcpy(path,vget("PATH")); for (times=0;times<HSHSIZ;times++) { hasharray[times].name=0; --- 196,202 ----- return; } strcpy(path,vget("PATH")); + /* free up previous hash table */ for (times=0;times<HSHSIZ;times++) { free(hasharray[times].name); *************** *** 198,205 strcpy(path,vget("PATH")); for (times=0;times<HSHSIZ;times++) { ! hasharray[times].name=0; ! hasharray[times].exec_ptr.dir=EOS; } h_hits=h_misses=0; /* reset hashing stats */ /* hash builtins here if not in PATH variable. */ --- 199,209 ----- /* free up previous hash table */ for (times=0;times<HSHSIZ;times++) { ! free(hasharray[times].name); ! hasharray[times].name=NULL; ! if (!hasharray[times].type) ! free(hasharray[times].exec_ptr.dir); ! hasharray[times].exec_ptr.dir=NULL; } h_hits=h_misses=0; /* reset hashing stats */ /* hash builtins here if not in PATH variable. */ *************** *** 223,228 if (hashbuiltins()) return; /* ditto */ continue; } /* shouldn't have to malloc for entry since opendir does it, hopefully */ if ((dd=opendir(dir))!=NULL) { --- 227,283 ----- if (hashbuiltins()) return; /* ditto */ continue; } + if (dir[0]=='.' && dir[1]==EOS) + { + /* + Hash '.' separately so that we can check for executables. We'll do it + here instead of checking in the loop below because it's more efficient. + We only have to check once for each directory on the path (~10), not for + each file on the path (~600). This has been added to avoid the full hashtable + syndrome which isn't harmful with dot at the end of the path, but annoying, + nevertheless. First open it, then check each one. + */ + if ((dd=opendir("."))!=NULL) + { + while ((entry=readdir(dd))!=NULL) + { + if (entry->d_name[0]=='.' && (entry->d_name[1]==EOS || entry->d_name[1]=='.')) continue; + if (!executable(entry->d_name,"",1)) continue; + hashval=hash(entry->d_name); + for (times=0;hasharray[hashval].name!=NULL && times<HSHSIZ;times++) + { + hashval++; + hashval%=HSHSIZ; + } + if (times==0) h_hits++; + else + { + #ifdef DEBUG + fprintf(stderr,"Hash missed on %d\n",hash(entry->d_name)); + #endif + h_misses++; + if (times==HSHSIZ) + { + write(2,"Hash table is full. Cannot complete hash.\n",42); + /* allow the partial hash and just return */ + return; + } + } + + /* Having found a blank position we now malloc some space and copy the values */ + hasharray[hashval].name=(char *) malloc ((unsigned)(strlen(entry->d_name)+1)); + strcpy(hasharray[hashval].name,entry->d_name); + hasharray[hashval].exec_ptr.dir=(char *) malloc ((unsigned)(strlen(dir)+1)); + strcpy(hasharray[hashval].exec_ptr.dir,dir); + hasharray[hashval].type=0; + } + closedir(dd); + } + else + fprintf(stderr,"Can't open directory: %s\n",dir); + } + + /* shouldn't have to malloc for entry since opendir does it, hopefully */ if ((dd=opendir(dir))!=NULL) { *************** *** 238,243 if (times==0) h_hits++; else { h_misses++; if (times==HSHSIZ) { --- 293,301 ----- if (times==0) h_hits++; else { + #ifdef DEBUG + fprintf(stderr,"Hash missed on %d\n",hash(entry->d_name)); + #endif h_misses++; if (times==HSHSIZ) { //E*O*F hash.cdif// echo x - header.hdif cat > "header.hdif" << '//E*O*F header.hdif//' *** ../Patch1/header.h Thu Jun 1 17:03:20 1989 --- header.h Thu Jun 1 16:55:28 1989 *************** *** 108,113 /* Some general defines */ #define EOS '\0' #define UNDEF -1 /* Identification for error codes for metacharacter expansion function */ #ifdef OK /* defined somewhere on minixST */ --- 108,114 ----- /* Some general defines */ #define EOS '\0' #define UNDEF -1 + #define NFILES 20 /* Identification for error codes for metacharacter expansion function */ #ifdef OK /* defined somewhere on minixST */ *************** *** 215,222 void insert(char *, int, int, int *); void show(char *, int *, bool); void goend(char *, int *, int *); ! void copyback(char *, int, int *); ! void delword(char *, int, int *); void backword(char *, int *, int *); void forword(char *, int *, int *); void yanknext(char *, int, char *); --- 216,224 ----- void insert(char *, int, int, int *); void show(char *, int *, bool); void goend(char *, int *, int *); ! void copyback(char *, int, int *, int); ! void delnextword(char *, int, int *); ! void delprevword(char *, int, int *); void backword(char *, int *, int *); void forword(char *, int *, int *); void yanknext(char *, int, char *); *************** *** 230,236 bool expand_tilde(char *, int *); void help(char *, int, int *); ! void setexec(void); void setbgexec(void); void resetsigdefaults(void); bool findslash(char *); --- 232,238 ----- bool expand_tilde(char *, int *); void help(char *, int, int *); ! void setexec(int); void setbgexec(void); void resetsigdefaults(void); bool findslash(char *); //E*O*F header.hdif// exit 0
wtoomey@gara.une.oz (Warren Toomey) (06/01/89)
# This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # job.cdif main.cdif meta.cdif echo x - job.cdif cat > "job.cdif" << '//E*O*F job.cdif//' *** ../Patch1/job.c Thu Jun 1 17:03:46 1989 --- job.c Thu Jun 1 16:55:54 1989 *************** *** 399,405 printf("\n%s\n",siglist[status.w_stopsig]); } else ! printf("\n%s\n",siglist[status.w_termsig]); fflush(stdout); } c=vget("cwd"); --- 399,408 ----- printf("\n%s\n",siglist[status.w_stopsig]); } else ! if (status.w_coredump) ! printf("\n%s (core dumped)\n",siglist[status.w_termsig]); ! else ! printf("\n%s\n",siglist[status.w_termsig]); fflush(stdout); } c=vget("cwd"); //E*O*F job.cdif// echo x - main.cdif cat > "main.cdif" << '//E*O*F main.cdif//' *** ../Patch1/main.c Thu Jun 1 17:04:26 1989 --- main.c Thu Jun 1 16:56:32 1989 *************** *** 277,282 termod->sg_flags &= (~ECHO); /* do not echo chars to screen */ if (ioctl(0,TIOCSETP,termod)) /* put it back, modified */ perror("ioctl"); setsigc=(struct tchars *) malloc ((unsigned)(sizeof(struct tchars))); if (ioctl(0,TIOCGETC,setsigc)) /* get the tchars struct */ perror("ioctl"); --- 277,283 ----- termod->sg_flags &= (~ECHO); /* do not echo chars to screen */ if (ioctl(0,TIOCSETP,termod)) /* put it back, modified */ perror("ioctl"); + free(termod); setsigc=(struct tchars *) malloc ((unsigned)(sizeof(struct tchars))); if (ioctl(0,TIOCGETC,setsigc)) /* get the tchars struct */ perror("ioctl"); *************** *** 281,287 if (ioctl(0,TIOCGETC,setsigc)) /* get the tchars struct */ perror("ioctl"); setsigc->t_intrc=(UNDEF); /* no interrupt or quitting */ ! /*setsigc->t_quitc=(UNDEF); allow quit while debugging */ setsigc->t_eofc=(UNDEF); /* or eof signalling */ if (ioctl(0,TIOCSETC,setsigc)) /* put it back, modified */ perror("ioctl"); --- 282,288 ----- if (ioctl(0,TIOCGETC,setsigc)) /* get the tchars struct */ perror("ioctl"); setsigc->t_intrc=(UNDEF); /* no interrupt or quitting */ ! /*setsigc->t_quitc=(UNDEF); Allow quit while debugging */ setsigc->t_eofc=(UNDEF); /* or eof signalling */ if (ioctl(0,TIOCSETC,setsigc)) /* put it back, modified */ perror("ioctl"); *************** *** 285,290 setsigc->t_eofc=(UNDEF); /* or eof signalling */ if (ioctl(0,TIOCSETC,setsigc)) /* put it back, modified */ perror("ioctl"); # ifndef MINIX moresigc.t_suspc=(UNDEF); /* no stopping */ moresigc.t_dsuspc=(UNDEF); /* or delayed stopping */ --- 286,292 ----- setsigc->t_eofc=(UNDEF); /* or eof signalling */ if (ioctl(0,TIOCSETC,setsigc)) /* put it back, modified */ perror("ioctl"); + free(setsigc); # ifndef MINIX moresigc.t_suspc=(UNDEF); /* no stopping */ moresigc.t_dsuspc=(UNDEF); /* or delayed stopping */ *************** *** 292,298 moresigc.t_flushc=(UNDEF); /* or flushing */ moresigc.t_werasc=(UNDEF); /* or word erasing */ moresigc.t_lnextc=(UNDEF); /* or literal quoting */ ! if (ioctl(0,TIOCSLTC,&moresigc)) /* set ltchars struct to be all undef */ perror("ioctl"); # endif #endif --- 294,300 ----- moresigc.t_flushc=(UNDEF); /* or flushing */ moresigc.t_werasc=(UNDEF); /* or word erasing */ moresigc.t_lnextc=(UNDEF); /* or literal quoting */ ! if (ioctl(0,TIOCSLTC,&moresigc)) /* set ltchars struct to be all undef */ perror("ioctl"); # endif #endif *************** *** 344,349 struct tchars *setsigc; # ifndef MINIX struct ltchars moresigc; # endif #ifdef DEBUG --- 346,352 ----- struct tchars *setsigc; # ifndef MINIX struct ltchars moresigc; + int pid; # endif #ifdef DEBUG *************** *** 357,362 termod->sg_flags &= (~ECHO); /* do not echo chars to screen */ if (ioctl(0,TIOCSETN,termod)) /* put it back, modified */ perror("ioctl"); setsigc=(struct tchars *) malloc ((unsigned)(sizeof(struct tchars))); if (ioctl(0,TIOCGETC,setsigc)) /* get the tchars struct */ perror("ioctl"); --- 360,366 ----- termod->sg_flags &= (~ECHO); /* do not echo chars to screen */ if (ioctl(0,TIOCSETN,termod)) /* put it back, modified */ perror("ioctl"); + free(termod); setsigc=(struct tchars *) malloc ((unsigned)(sizeof(struct tchars))); if (ioctl(0,TIOCGETC,setsigc)) /* get the tchars struct */ perror("ioctl"); *************** *** 365,370 setsigc->t_eofc=(UNDEF); /* or eof signalling */ if (ioctl(0,TIOCSETC,setsigc)) /* put it back, modified */ perror("ioctl"); # ifndef MINIX moresigc.t_suspc=(UNDEF); /* no stopping */ moresigc.t_dsuspc=(UNDEF); /* or delayed stopping */ --- 369,375 ----- setsigc->t_eofc=(UNDEF); /* or eof signalling */ if (ioctl(0,TIOCSETC,setsigc)) /* put it back, modified */ perror("ioctl"); + free(setsigc); # ifndef MINIX moresigc.t_suspc=(UNDEF); /* no stopping */ moresigc.t_dsuspc=(UNDEF); /* or delayed stopping */ *************** *** 374,379 moresigc.t_lnextc=(UNDEF); /* or literal quoting */ if (ioctl(0,TIOCSLTC,&moresigc)) /* set ltchars struct to be all undef */ perror("ioctl"); # endif #endif --- 379,386 ----- moresigc.t_lnextc=(UNDEF); /* or literal quoting */ if (ioctl(0,TIOCSLTC,&moresigc)) /* set ltchars struct to be all undef */ perror("ioctl"); + pid=getpid(); + if (ioctl(0,TIOCSPGRP,&pid)) perror("ioctl stpg"); # endif #endif *************** *** 451,457 else { /* either logout or exit according to invokename*/ if (loginsh==TRUE) logout(numargs,arguments); /* truncated args */ ! else write(1,"Exit\n",5); setdown(); exit(0); } --- 458,464 ----- else { /* either logout or exit according to invokename*/ if (loginsh==TRUE) logout(numargs,arguments); /* truncated args */ ! else write(1,"exit\n",5); setdown(); exit(0); } *************** *** 565,574 while (act!=ENDLN && act!=ERRER) { retval=0; ! #if 0 ! /* Was this: appears to be totally wrong */ ! act=intercom(line,&pos,&pid,FALSE,NULL,1); ! #else act=intercom(line,&pos,&pid,&i ,FALSE,1); /* call intercom with fromfile set -- ?? the big question is do we */ /* really ignore the value of outpfd - i dunno., could'nt make out, */ --- 572,581 ----- while (act!=ENDLN && act!=ERRER) { retval=0; ! ! /* Was this: appears to be totally wrong ! act=intercom(line,&pos,&pid,FALSE,NULL,1); */ ! act=intercom(line,&pos,&pid,&i ,FALSE,1); /* call intercom with fromfile set -- ?? the big question is do we */ /* really ignore the value of outpfd - I dunno., couldn't make out, */ *************** *** 571,578 #else act=intercom(line,&pos,&pid,&i ,FALSE,1); /* call intercom with fromfile set -- ?? the big question is do we */ ! /* really ignore the value of outpfd - i dunno., could'nt make out, */ ! /* so i just put in &i, otherwise obviusly this call causes bombs in */ /* intercom() */ #endif #if 0 --- 578,585 ----- act=intercom(line,&pos,&pid,&i ,FALSE,1); /* call intercom with fromfile set -- ?? the big question is do we */ ! /* really ignore the value of outpfd - I dunno., couldn't make out, */ ! /* so I just put in &i, otherwise obviously this call causes bombs in */ /* intercom() */ for (i=3;i<=NFILES;i++) if (i!=fileno(finp)) close(i); if (pid && act!=BCKGND) *************** *** 574,583 /* really ignore the value of outpfd - i dunno., could'nt make out, */ /* so i just put in &i, otherwise obviusly this call causes bombs in */ /* intercom() */ - #endif - #if 0 - for (i=3;i<=20;i++) if (i!=fileno(finp)) close(i); - #else for (i=3;i<=NFILES;i++) if (i!=fileno(finp)) close(i); #endif if (pid && act!=BCKGND) --- 581,586 ----- /* really ignore the value of outpfd - I dunno., couldn't make out, */ /* so I just put in &i, otherwise obviously this call causes bombs in */ /* intercom() */ for (i=3;i<=NFILES;i++) if (i!=fileno(finp)) close(i); if (pid && act!=BCKGND) retval=waitfor(pid); *************** *** 579,585 for (i=3;i<=20;i++) if (i!=fileno(finp)) close(i); #else for (i=3;i<=NFILES;i++) if (i!=fileno(finp)) close(i); - #endif if (pid && act!=BCKGND) retval=waitfor(pid); if (!disable_auto && act==ERRER) exit(1); /* exit on shell syntax error */ --- 582,587 ----- /* so I just put in &i, otherwise obviously this call causes bombs in */ /* intercom() */ for (i=3;i<=NFILES;i++) if (i!=fileno(finp)) close(i); if (pid && act!=BCKGND) retval=waitfor(pid); if (!disable_auto && act==ERRER) exit(1); /* exit on shell syntax error */ *************** *** 753,762 while (act!=ENDLN && act!=ERRER) { retval=0; ! #if 0 ! /* WAS: same intercom problem as in file() here */ ! act=intercom(line,&pos,&pid,FALSE,NULL,0); ! #else act=intercom(line,&pos,&pid, &i, FALSE,0); /* call intercom with fromfile not set */ #endif #if 0 --- 755,764 ----- while (act!=ENDLN && act!=ERRER) { retval=0; ! ! /* WAS: same intercom problem as in file() here ! act=intercom(line,&pos,&pid,FALSE,NULL,0); */ ! act=intercom(line,&pos,&pid, &i, FALSE,0); /* call intercom with fromfile not set */ for (i=3;i<=NFILES;i++) close(i); *************** *** 758,767 act=intercom(line,&pos,&pid,FALSE,NULL,0); #else act=intercom(line,&pos,&pid, &i, FALSE,0); /* call intercom with fromfile not set */ ! #endif ! #if 0 ! for (i=3;i<=20;i++) close(i); ! #else for (i=3;i<=NFILES;i++) close(i); #endif if (pid && act!=BCKGND) --- 760,766 ----- act=intercom(line,&pos,&pid,FALSE,NULL,0); */ act=intercom(line,&pos,&pid, &i, FALSE,0); /* call intercom with fromfile not set */ ! for (i=3;i<=NFILES;i++) close(i); if (pid && act!=BCKGND) retval=waitfor(pid); *************** *** 763,769 for (i=3;i<=20;i++) close(i); #else for (i=3;i<=NFILES;i++) close(i); - #endif if (pid && act!=BCKGND) retval=waitfor(pid); #ifndef MINIX --- 762,767 ----- act=intercom(line,&pos,&pid, &i, FALSE,0); /* call intercom with fromfile not set */ for (i=3;i<=NFILES;i++) close(i); if (pid && act!=BCKGND) retval=waitfor(pid); #ifndef MINIX *************** *** 819,828 while (act!=ENDLN && act!=ERRER) { retval=0; - #if 0 - /* WAS: sample problem */ - act=intercom(line,&pos,&pid,FALSE,NULL,0); /* call intercom with fromfile not set */ - #else act=intercom(line,&pos,&pid, &i,FALSE,0); /* call intercom with fromfile not set */ #endif #if 0 --- 817,822 ----- while (act!=ENDLN && act!=ERRER) { retval=0; act=intercom(line,&pos,&pid, &i,FALSE,0); /* call intercom with fromfile not set */ for (i=3;i<=NFILES;i++) close(i); if (pid && act!=BCKGND) *************** *** 824,833 act=intercom(line,&pos,&pid,FALSE,NULL,0); /* call intercom with fromfile not set */ #else act=intercom(line,&pos,&pid, &i,FALSE,0); /* call intercom with fromfile not set */ - #endif - #if 0 - for (i=3;i<=20;i++) close(i); - #else for (i=3;i<=NFILES;i++) close(i); #endif if (pid && act!=BCKGND) --- 818,823 ----- { retval=0; act=intercom(line,&pos,&pid, &i,FALSE,0); /* call intercom with fromfile not set */ for (i=3;i<=NFILES;i++) close(i); if (pid && act!=BCKGND) retval=waitfor(pid); *************** *** 829,835 for (i=3;i<=20;i++) close(i); #else for (i=3;i<=NFILES;i++) close(i); - #endif if (pid && act!=BCKGND) retval=waitfor(pid); #ifndef MINIX --- 819,824 ----- retval=0; act=intercom(line,&pos,&pid, &i,FALSE,0); /* call intercom with fromfile not set */ for (i=3;i<=NFILES;i++) close(i); if (pid && act!=BCKGND) retval=waitfor(pid); #ifndef MINIX //E*O*F main.cdif// echo x - meta.cdif cat > "meta.cdif" << '//E*O*F meta.cdif//' *** ../Patch1/meta.c Thu Jun 1 17:05:18 1989 --- meta.c Thu Jun 1 16:57:22 1989 *************** *** 172,178 i=0; while (!feof(progout)) { ! c = getc(progout); #ifdef DEBUG fprintf(stderr,"%o",c); #endif --- 172,178 ----- i=0; while (!feof(progout)) { ! if ((c = getc(progout))==EOF) break; #ifdef DEBUG fprintf(stderr,"%o",c); #endif *************** *** 406,412 char *line,*word; int *pos; { ! int l=1,insym=0,inword=0,i=0; word[0]=EOS; while(l) --- 406,412 ----- char *line,*word; int *pos; { ! int l=1,insym=0,inword=0,i=0,quote=0; word[0]=EOS; while(l) *************** *** 437,442 } else (*pos)++; break; default: if (insym) { --- 437,445 ----- } else (*pos)++; break; + case '"': + while((word[i++]=line[(*pos)++])!='"'); + break; default: if (insym) { *************** *** 689,694 j=0; while ((err=loadpattern(line,&i,word,&pattern))==FINE) { if (pattern==FALSE) /* if no * ? [] then add to line */ { if (j!=0) newline[j++]=' '; --- 692,700 ----- j=0; while ((err=loadpattern(line,&i,word,&pattern))==FINE) { + #ifdef DEBUG + fprintf(stderr,"word was %s<\n",word); + #endif if (pattern==FALSE) /* if no * ? [] then add to line */ { if (j!=0) newline[j++]=' '; *************** *** 697,702 newline[j]=EOS; continue; } /* if an absolute path name is given, then chop it off the front of word and put it in dir. Now word contains the patterned stuff onwards. */ finddir(word,dir); --- 703,711 ----- newline[j]=EOS; continue; } + #ifdef DEBUG + fprintf(stderr,"newline in pattern_match\n%s\n",newline); + #endif /* if an absolute path name is given, then chop it off the front of word and put it in dir. Now word contains the patterned stuff onwards. */ finddir(word,dir); *************** *** 1145,1150 if (m_err=curly(line)) return(m_err); if (Tilde==TRUE) if (m_err=tilde(line)) return(m_err); if (Pattern==TRUE) if (m_err=pattern_match(line)) return(m_err); if (Bquote==TRUE) --- 1154,1162 ----- if (m_err=curly(line)) return(m_err); if (Tilde==TRUE) if (m_err=tilde(line)) return(m_err); + #ifdef DEBUG + fprintf(stderr,"line before pattern_match\n%s\n",line); + #endif if (Pattern==TRUE) if (m_err=pattern_match(line)) return(m_err); #ifdef DEBUG *************** *** 1147,1152 if (m_err=tilde(line)) return(m_err); if (Pattern==TRUE) if (m_err=pattern_match(line)) return(m_err); if (Bquote==TRUE) if (m_err=backquote(line)) return(m_err); --- 1159,1167 ----- #endif if (Pattern==TRUE) if (m_err=pattern_match(line)) return(m_err); + #ifdef DEBUG + fprintf(stderr,"line after pattern_match\n%s\n",line); + #endif if (Bquote==TRUE) if (m_err=backquote(line)) return(m_err); //E*O*F meta.cdif// exit 0