Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site seismo.UUCP Posting-Version: version B 2.10.2 9/3/84; site genrad.UUCP Path: seismo!harvard!talcott!panda!genrad!sources-request From: sources-request@genrad.UUCP Newsgroups: mod.sources Subject: bm bug fix Message-ID: <1005@genrad.UUCP> Date: 6 Aug 85 13:40:14 GMT Sender: john@genrad.UUCP Lines: 112 Approved: john@genrad.UUCP Mod.sources: Volume 2, Issue 36 Submitted by: seismo!mcvax!ken (Ken Yap) Problem: Bm quits when encountering an unreadable file (no permission, file does not exist) with an exit status of 2. The grep family prints an error message and continues searching. Repeat-by: # in some directory with a C main program echo main > xxx chmod 200 xxx bm main xxx *.c # compare with grep main xxx *.c Fix: Apply the patch below. *** bm.c.old Tue Aug 6 10:34:57 1985 --- bm.c Tue Aug 6 10:41:22 1985 *************** *** 17,22 * machines which would complain) */ int ret = 1, /* return code from Execute */ NFiles, NPats; /* number of patterns to search for */ char i, --- 17,23 ----- * machines which would complain) */ int ret = 1, /* return code from Execute */ + NotFound = 0, /* non-zero if file not readable */ NFiles, NPats; /* number of patterns to search for */ char i, *************** *** 76,82 if ((NFiles > 1) || lFlag) FileName = *OptPtr; if ((TextFile = open(*OptPtr,O_RDONLY,0)) < 0) { fprintf(stderr,"bm: can't open %s\n",*OptPtr); ! exit(2); } /* if */ ret &= Execute(DescVec,NPats,TextFile,BigBuff+1); if (sFlag && !ret) --- 77,89 ----- if ((NFiles > 1) || lFlag) FileName = *OptPtr; if ((TextFile = open(*OptPtr,O_RDONLY,0)) < 0) { fprintf(stderr,"bm: can't open %s\n",*OptPtr); ! NotFound++; ! } ! else { ! ret &= Execute(DescVec,NPats,TextFile,BigBuff+1); ! if (sFlag && !ret) ! exit(0); ! close(TextFile); } /* if */ ++OptPtr; } /* while */ *************** *** 78,86 fprintf(stderr,"bm: can't open %s\n",*OptPtr); exit(2); } /* if */ - ret &= Execute(DescVec,NPats,TextFile,BigBuff+1); - if (sFlag && !ret) - exit(0); ++OptPtr; close(TextFile); } /* while */ --- 85,90 ----- exit(0); close(TextFile); } /* if */ ++OptPtr; } /* while */ if (cFlag) printf("%d\n",MatchCount); *************** *** 82,88 if (sFlag && !ret) exit(0); ++OptPtr; - close(TextFile); } /* while */ if (cFlag) printf("%d\n",MatchCount); exit(ret); --- 86,91 ----- close(TextFile); } /* if */ ++OptPtr; } /* while */ if (cFlag) printf("%d\n",MatchCount); exit(NotFound ? 2 : ret); *************** *** 85,89 close(TextFile); } /* while */ if (cFlag) printf("%d\n",MatchCount); ! exit(ret); } /* main */ --- 88,92 ----- ++OptPtr; } /* while */ if (cFlag) printf("%d\n",MatchCount); ! exit(NotFound ? 2 : ret); } /* main */ Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site seismo.UUCP Posting-Version: version B 2.10.2 9/3/84; site genrad.UUCP Path: seismo!harvard!talcott!panda!genrad!sources-request From: sources-request@genrad.UUCP Newsgroups: mod.sources Subject: bm (update to 1.1) Message-ID: <982@genrad.UUCP> Date: 25 Jul 85 20:34:38 GMT Sender: john@genrad.UUCP Lines: 124 Approved: john@genrad.UUCP Mod.sources: Volume 2, Issue 19 Submitted by: Peter Bain Jeff Mogul (mogul@Carmel) pointed out a bug and kindly provided the fix. The last line in the buffer was getting thrown away or mangled, due to an error in arguments to MoveResidue. This occurred only in long files. The correction to Execute.c is: *** 78,84 } /* for */ } /* while */ if(NRead) { ! ResSize = MoveResidue(DescVec,NPats,Buffer,BuffEnd); BuffPos += BuffSize - ResSize; } /* if */ } while (NRead); --- 78,85 ----- } /* for */ } /* while */ if(NRead) { ! ResSize = MoveResidue(DescVec,NPats,Buffer, ! Buffer + BuffSize - 1); BuffPos += BuffSize - ResSize; } /* if */ } while (NRead); The correct code for Execute.c is ----------------------- go into scissor mode here ------------------ : This is a shar archive. Extract with sh, not csh. : The rest of this file will extract: : Execute.c echo Extracting Execute.c sed 's/^X//' > Execute.c << 'e-o-f' X#include X#include "bm.h" X#include "Extern.h" XExecute(DescVec, NPats, TextFile, Buffer) Xstruct PattDesc *DescVec[]; /* pointers to status vectors for the different X * patterns, including skip tables, position in buffer, etc. */ Xint NPats; /* number of patterns */ Xchar Buffer[]; /* holds text from file */ Xint TextFile; /* file to search */ X{ X int NRead, /* number of chars read from file */ X NWanted, /* number of chars wanted */ X NAvail, /* number of chars actually read */ X BuffSize, /* number of chars in buffer */ X BuffPos, /* offset of first char in Buffer in TextFile */ X BuffEx, /* flag to indicate that buffer has been searched */ X ResSize, X /* number of characters in the last, incomplete line */ X Found, /* flag indicates whether pattern found X * completely and all matches printed */ X Valid; /* was the match "valid", i.e. if -x used, X * did the whole line match? */ X char *BuffEnd; /* pointer to last char of last complete line */ X X /* misc working variables */ X int i; X X /* initialize */ X ResSize = 0; X Found = 0; X BuffPos = 0; X for (i=0; i < NPats; i++) { X DescVec[i] -> Success = 0; X DescVec[i] -> Start = Buffer; X } /* for */ X /* now do the searching */ X do { X /* first, read a bufferfull and set up the variables */ X NWanted = MAXBUFF - ResSize; NRead = 0; X do { X NAvail = X read(TextFile,Buffer + ResSize + NRead, NWanted); X if (NAvail == -1) { X fprintf(stderr, X "bm: error reading from input file\n"); X exit(2); X } /* if */ X NRead += NAvail; NWanted -= NAvail; X } while (NAvail && NWanted); X BuffEx = 0; X BuffSize = ResSize + NRead; X BuffEnd = Buffer + BuffSize - 1; X /* locate the end of the last complete line */ X while (*BuffEnd != '\n' && BuffEnd >= Buffer) X --BuffEnd; X if (BuffEnd < Buffer) X BuffEnd = Buffer + BuffSize - 1; X while (!BuffEx) { /* work through one buffer full */ X BuffEx = 1; /* set it provisionally, then clear X * it if we find the buffer non-empty */ X for (i=0; i< NPats; i++) { X if (!DescVec[i]->Success) X /* if the pattern has not been found */ X DescVec[i]-> Success = X Search(DescVec[i]->Pattern, X DescVec[i]->PatLen, Buffer, BuffEnd, X DescVec[i]->Skip1, DescVec[i]->Skip2, X DescVec[i]); X if (DescVec[i]->Success){ X /* if a match occurred */ X BuffEx = 0; X Valid = MatchFound(DescVec[i],BuffPos, X Buffer, BuffEnd); X Found |= Valid; X if ((sFlag || lFlag) && Found) X return(0); X } /* if */ X } /* for */ X } /* while */ X if(NRead) { X ResSize = MoveResidue(DescVec,NPats,Buffer, X Buffer + BuffSize -1); X BuffPos += BuffSize - ResSize; X } /* if */ X } while (NRead); X return(!Found); X} /* Execute */ e-o-f exit 0