Subject: cmp, more
To: None <netbsd-bugs@sun-lamp.cs.berkeley.edu>
From: Xavier Leroy <xavier@Theory.Stanford.EDU>
List: netbsd-bugs
Date: 12/01/1993 16:29:04
You will find below a bug fix and a small improvement I suggest for
cmp and more, respectively.

Regards,

- Xavier Leroy

------------------------------ cmp ------------------------------

Symptom: if the second file is standard input and does not come from a
  file, cmp stops before reaching the end of the second file.

How to reproduce:  cat /netbsd | cmp /netbsd -
  Will report "EOF on file -", or something like that.

Cause: cmp calls read() to read N characters from the second file,
  and considers that it has reached EOF if it gets less than N
  characters back.

Fix:

*** cmp.c~	Sun Mar 21 01:54:12 1993
--- cmp.c	Sun Nov 14 18:48:10 1993
***************
*** 170,178 ****
  		 * file1 might be stdio, which means that a read of less than
  		 * MAXBSIZE might not mean an EOF.  So, read whatever we read
  		 * from file1 from file2.
  		 */
! 		if ((len2 = read(fd2, buf2, len1)) == -1)
! 			error(file2);
  		if (bcmp(buf1, buf2, len2)) {
  			if (silent)
  				exit(EXITDIFF);
--- 170,183 ----
  		 * file1 might be stdio, which means that a read of less than
  		 * MAXBSIZE might not mean an EOF.  So, read whatever we read
  		 * from file1 from file2.
+ 		 * Several reads may be required if file2 is stdio.
  		 */
! 		for (len2 = 0; len2 < len1; ) {
! 			cnt = read(fd2, buf2 + len2, len1 - len2);
! 			if (cnt == -1) error(file2);
! 			if (cnt == 0) break;
! 			len2 += cnt;
! 		}
  		if (bcmp(buf1, buf2, len2)) {
  			if (silent)
  				exit(EXITDIFF);


------------------------------ more ------------------------------

Symptom: when the user types "/<RET>", more searchs for the next
  occurrence of the empty regexp, instead of searching for the next
  occurrence of the last regexp used with /, as many implementations of
  more do.

Rationale: OK, that's not a bug, but I'm very much used to type
  "/<RET>" to look for the next occurrence of a regexp. Typing "."
  does not work if the last command was not a search.

Fix:

*** more.c.orig	Tue Oct 12 21:33:58 1993
--- more.c	Tue Oct 12 21:46:00 1993
***************
*** 130,136 ****
  int		ulglitch;	/* terminal has underline mode glitch */
  int		pstate = 0;	/* current UL state */
  char		*getenv();
! regexp		*previous;	/* previous regular expression */
  struct {
      long chrctr, line;
  } context, screen_start;
--- 130,136 ----
  int		ulglitch;	/* terminal has underline mode glitch */
  int		pstate = 0;	/* current UL state */
  char		*getenv();
! regexp		*previous = NULL;	/* previous regular expression */
  struct {
      long chrctr, line;
  } context, screen_start;
***************
*** 1145,1151 ****
  	    else {
  		ttyin (cmdbuf, 78, '/');
  		write (2, "\r", 1);
! 		search (cmdbuf, f, nlines);
  	    }
  	    ret (dlines-1);
  	case '!':
--- 1145,1151 ----
  	    else {
  		ttyin (cmdbuf, 78, '/');
  		write (2, "\r", 1);
! 		search (cmdbuf[0] ? cmdbuf : NULL, f, nlines);
  	    }
  	    ret (dlines-1);
  	case '!':
***************
*** 1331,1338 ****
      lncount = 0;
      if (buf)
  	previous = s = regcomp (buf);
!     else
  	s = previous;
      while (!feof (file)) {
  	line3 = line2;
  	line2 = line1;
--- 1331,1340 ----
      lncount = 0;
      if (buf)
  	previous = s = regcomp (buf);
!     else {
! 	if (previous == NULL) error("No previous regular expression");
  	s = previous;
+     }
      while (!feof (file)) {
  	line3 = line2;
  	line2 = line1;

------------------------------------------------------------------------------