🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Chet Ramey Fri, 30 Jun 1989 18:53
fixes for test.c (bash 1.01)
#180
Author: Chet Ramey
Date: Fri, 30 Jun 1989 18:53
314 lines
7875 bytes
There are a few problems with the test builtin as released with bash 1.01.

1.  I claim that test handles the unary negation operator (`!') incorrectly.
    Here is the test program I used:

	if [ ! -d /usr -a ! -d /etc ] ; then
		echo "Bogus"
	else
		echo "OK"
	fi

    I claim that "OK" should be echoed (on any Unix system).  The following 
    Bourne-style shells agree with me:
		4.3 BSD 	/bin/sh
		SunOS 3.5 	/bin/sh	(s5r2-based)
		Ultrix 3.0	/bin/sh (4.2 BSD +)
		ksh version 06/03/86b
		Ultrix 3.0	/bin/sh5 (s5r2 shell)
		AIX 2.2.1	/bin/sh
		s5r2 		/bin/sh
		s5r3.2		/bin/sh
		ash			 (Kenneth Almquist's shell)

    Vanilla Bash 1.01 echos "[: too many arguments".  The problem is that
    "!" is recognized and handled in expr(), not in term().  The fix is
    simple.

2.  The precendeces of -a and -o are switched.  Fixes for this have already
    been posted by andy@csvax.caltech.edu (<8906240223.AA27273@csvax.caltech.edu>);
    I mention them only because they are also in the diffs.

3.  I posted a fix for the test_syntax_error problem yesterday (6/28); that
    patch is in here.

4.  The problem with -w, as reported by Peter Su (hugo@GRIGGS.DARTMOUTH.EDU),
    can be fixed by using access().  I changed -r to do so as well (-x already
    did).

*** bash-1.01/test.c	Fri Jun 23 00:43:13 1989
--- src-1.01/test.c	Fri Jun 30 12:57:05 1989
***************
*** 33,39 ****
  #include <sys/stat.h>
  #include <sys/file.h>
! #ifndef X_OK
  #define X_OK 1
! #endif
  #ifndef lint
  static char *rcsid="$Id: gtest.c,v 1.10 88/07/02 13:34:45 afb Exp Locker: afb $";
--- 33,42 ----
  #include <sys/stat.h>
  #include <sys/file.h>
! #ifndef R_OK
! #define R_OK 4
! #define W_OK 2
  #define X_OK 1
! #define F_OK 0
! #endif /* R_OK */
  #ifndef lint
  static char *rcsid="$Id: gtest.c,v 1.10 88/07/02 13:34:45 afb Exp Locker: afb $";
***************
*** 67,71 ****
--- 70,78 ----
  #endif  /* STANDALONE */
  
+ #ifndef SYSV
  int sys_v = 0;
+ #else
+ int sys_v = 1;
+ #endif
  
  static int pos;			/* position in list			*/
***************
*** 73,76 ****
--- 80,84 ----
  static char **argv;		/* the argument list			*/
  
+ #ifndef SYSV
  static void
  test_syntax_error (pchFmt, args)
***************
*** 84,87 ****
--- 92,110 ----
  }
  
+ #else
+ #include <varargs.h>
+ 
+ static void
+ test_syntax_error(fmt, va)
+ char *fmt;
+ va_list va;
+ {
+   (void) fprintf(stderr,"%s: ", argv[0]);
+   (void) vfprintf(stderr, fmt, va);
+   (void) fflush(stderr);                /* just in case */
+   test_exit(SHELL_BOOLEAN(FALSE));
+ }
+ #endif /* SYSV */
+ 
  test_io_error (name)
       char *name;
***************
*** 195,198 ****
--- 218,222 ----
   *
   * term ::= 
+  *	'!' term
   *	'-'('h'|'d'|'f'|'r'|'s'|'w'|'c'|'b'|'p'|'u'|'g'|'k') filename
   *	'-'('L'|'x') filename
***************
*** 217,221 ****
  				 * expressions of the form '-l string'? 
  				 */
!   auto int value, fd;
  
    if (pos >= argc)
--- 241,245 ----
  				 * expressions of the form '-l string'? 
  				 */
!   auto int value;
  
    if (pos >= argc)
***************
*** 222,225 ****
--- 246,262 ----
      beyond();
  
+   if ('!' == argv[pos][0] && '\000' == argv[pos][1])
+     {
+       value = FALSE;
+ 
+       /* Deal with leading "not"s. */
+       while (pos < argc && '!' == argv[pos][0] && '\000' == argv[pos][1])
+         {
+           advance(1);
+           value ^= (TRUE);
+ 	}
+       return (value ^ term());		/* recursive descent */
+     }
+ 
    if ('(' == argv[pos][0] && '\000' == argv[pos][1])
      {
***************
*** 469,476 ****
  	case 'r':		/* file is readable? */
  	  unary_advance ();
! 	  fd = open (argv[pos - 1], O_RDONLY, 0600);
! 	  if (value = fd != -1)
! 	    close (fd);
! 
  	  return (TRUE == value);
  
--- 506,510 ----
  	case 'r':		/* file is readable? */
  	  unary_advance ();
! 	  value = -1 != access (argv[pos - 1], R_OK);
  	  return (TRUE == value);
  
***************
*** 477,487 ****
  	case 'w':		/* File is writeable? */
  	  unary_advance ();
! 	  fd = open (argv[pos - 1], O_WRONLY, 0600);
! 	  if (value = fd != -1)
! 	    close (fd);
! 
  	  return (TRUE == value);
  
! 	case 'x':		/* File is executable? */
  	  unary_advance ();
  	  value = -1 != access (argv[pos - 1], X_OK);
--- 511,518 ----
  	case 'w':		/* File is writeable? */
  	  unary_advance ();
! 	  value = -1 != access (argv[pos - 1], W_OK);
  	  return (TRUE == value);
  
! 	case 'x':		/* File is executable?  Should we use executable_file() for this?*/
  	  unary_advance ();
  	  value = -1 != access (argv[pos - 1], X_OK);
***************
*** 600,609 ****
  
  /*
!  * or:
!  *	or '-o' term
   *	term
   */
  static int
! or ()
  {
    auto int value;
--- 631,640 ----
  
  /*
!  * and:
!  *	and '-a' term
   *	term
   */
  static int
! and ()
  {
    auto int value;
***************
*** 610,616 ****
  
    value = term ();
!   while (pos < argc && '-' == argv[pos][0] && 'o' == argv[pos][1] && '\000' == argv[pos][2]) {
      advance(0);
!     value = TRUTH_OR (value, term ());
    }
    return (TRUE == value);
--- 641,647 ----
  
    value = term ();
!   while (pos < argc && '-' == argv[pos][0] && 'a' == argv[pos][1] && '\000' == argv[pos][2]) {
      advance(0);
!     value = TRUTH_AND (value, term ());
    }
    return (TRUE == value);
***************
*** 618,634 ****
  
  /*
!  * and:
!  *	and '-a' or
!  *	or
   */
  static int
! and()
  {
    auto int value;
  
!   value = or();
!   while (pos < argc && '-' == argv[pos][0] && 'a' == argv[pos][1] && '\000' == argv[pos][2]) {
!     advance(1);
!     value = TRUTH_AND (value, or());
    }
    return (TRUE == value);
--- 649,665 ----
  
  /*
!  * or:
!  *	or '-o' and
!  *	and
   */
  static int
! or()
  {
    auto int value;
  
!   value = and();
!   while (pos < argc && '-' == argv[pos][0] && 'o' == argv[pos][1] && '\000' == argv[pos][2]) {
!     advance(0);
!     value = TRUTH_OR (value, and());
    }
    return (TRUE == value);
***************
*** 637,642 ****
  /*
   * expr:
!  *	'!' expr
!  *	and
   */
  int
--- 668,672 ----
  /*
   * expr:
!  *	or
   */
  int
***************
*** 643,660 ****
  expr()
  {
-   auto int value;
- 
    if (pos >= argc)
      beyond();
!   value = FALSE;
! 
!   /* Deal with leading "not"'s. */
!   while (pos < argc && '!' == argv[pos][0] && '\000' == argv[pos][1]) {
!     advance(1);
! 
!     /* This has to be rewritten to handle the TRUTH and FALSE stuff. */
!     value ^= (TRUE);
!   }
!   return value ^ and();		/* Same with this. */
  }
  
--- 673,679 ----
  expr()
  {
    if (pos >= argc)
      beyond();
!   return FALSE ^ or();		/* Same with this. */
  }
  
***************
*** 687,690 ****
--- 706,710 ----
        test_exit (SHELL_BOOLEAN (FALSE));
      if (']' != margv[margc][0] || '\000' != margv[margc][1]) {
+       argv = margv;				/* for test_syntax_error */
        test_syntax_error ("missing `]'\n");
      }

Chet Ramey			"We are preparing to think about contemplating 
Network Services Group, CWRU	 preliminary work on plans to develop a
chet@cwjcc.INS.CWRU.Edu		 schedule for producing the 10th Edition of 
				 the Unix Programmers Manual." -- Andrew Hume
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads