🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.bash.bug
Article #824

Bash 1.04 Xenix diffs + general bug fixes

#824
From: gson
Date: Sun, 10 Dec 1989 16:23
682 lines
20966 bytes
I recently compiled Bash 1.04 on a '386 clone running SCO Xenix 386
version 2.3.2, development system version 2.2.  I have summarized 
the necessary changes below.  They include fixing several 
system-dependent bugs.  I have reported two apparently system-independent 
bugs separately.

The diffs to the Makefile apply to Xenix only.  They are included
just to help other people bring up bash on Xenix, not to be patched
into the distribution.  The diffs to other files are supposed to
be either general bug fixes useful for multiple machines (mostly SYSV
machines) or Xenix-specific changes enclosed in #ifdef XENIX.

I have not changed things that cause various warning messages
from the Xenix C compiler, like "string too big", because they
are rather benign and it's really the compiler that ought to be
fixed, not Bash.

Xenix also has its own ideas about directory functions; I fixed this
not by adding ugly #ifdef's everywhere but by creating a file
/usr/include/ndir.h containing the lines

	#define direct dirent
	#include <sys/ndir.h>

This usually also simplifies porting other applications to Xenix.

The order of the arguments to "setvbuf" in XENIX is different from
everyone else; I added an #ifdef XENIX in shell.c to swap them.
Beware of this if you have a fixed library.

There seems to be much confusion about "extern" and "static"
directives in builtins.c, apparently as a result of using an overly
lax C compiler during Bash development.  This was also reported by
someone else also a while ago.  Fixed in the diffs below.

There are several problems with the "union wait" definition for
i386/ATT3B/ATT386 in jobs.h.  First problem: status.w_termsig is an
r-value and cannot be assigned a value as is currently done in
nojobs.c.  Second problem: the macros status.w_termsig and w_coredump
are not (and, in their present form, cannot be) enclosed in
parentheses, causing operator precedence problems.  In particular, the
expression "if (status.w_termsig != 0 && status.w_termsig !=
WSTOPPED)" in nojobs.c will not have the intended meaning because of
incorrect operator precedence.  Third problem: the macro for
w_coredump is apparently plain wrong, expanding to "bytes.low & 0x7f &
~0x7f" which is always zero.  I have solved these problems for Xenix
by redefining "union wait" using bitfields, taking into account the
fact that the Xenix C compiler allocates bitfields starting at the
least significant bit.  Although the change is currently enclosed in
#ifdef XENIX, I suggest that this union definition be used
also for other architectures whose compilers allocate bitfields
starting at the LSB.

Xenix lacks sigignore() which is used in nojobs.c; I'm not
sure my fix is a correct one.  Check it out.

In jobs.c there is code for restoring the tty state when a command
terminates abnormally; this code was mostly absent in nojobs.c.

In glob.c I replaced every instance of the string USG by SYSV.  That's
what all the other files use.

"readline.c", around line 2116: turning off ISIG is not enough because
hitting BREAK also causes a SIGINT.  We need to both turn off
ISIG and turn on IGNBRK.

At least "builtins.c", "shell.c", and "glob.c" use "#ifdef SYSV"
before including either "config.h" or "shell.h", although on HPUX and
XENIX machines SYSV doesn't get defined until "config.h" has been
included (usually through "shell.h").

Last but not least, I have changed Bash and newversion.c so that
Bash uses a character string instead of a "float" variable to store
its version number.  This is actually the only place where Bash uses
floating point, and on my system it caused the size of the executable
to increase by about 4K because of floating-point libraries that were
linked in.  newversion.c still uses floating point.

Context diffs follow the .signature.
-- 
Andreas Gustafsson
Internet: gson@joker.hut.fi
Voice: +358 0 563 5592
================================ Cut here ================================
diff -c bash-1.04/Makefile bash/Makefile
*** bash-1.04/Makefile	Sat Nov  4 15:36:18 1989
--- bash/Makefile	Sat Dec  9 23:38:03 1989
***************
*** 33,43 ****
  #
  # The mailing address of you, the local maintainer.  This *must* be
  # enclosed in double quotes.  Until I make a better Makefile.
! MAINTAINER = '"bfox@ai.mit.edu"'
  
  # Destination installation directory.  The shell is copied here if
  # you do a `make install'.  The directory name does NOT end in a slash.
! DESTDIR = /usr/gnu/bin
  
  # The name of the target hardware.  It makes a difference.  If your
  # machine doesn't seem to be represented by one of the machines here,
--- 33,43 ----
  #
  # The mailing address of you, the local maintainer.  This *must* be
  # enclosed in double quotes.  Until I make a better Makefile.
! MAINTAINER = '"gson"'
  
  # Destination installation directory.  The shell is copied here if
  # you do a `make install'.  The directory name does NOT end in a slash.
! DESTDIR = /u/bin
  
  # The name of the target hardware.  It makes a difference.  If your
  # machine doesn't seem to be represented by one of the machines here,
***************
*** 45,56 ****
  # Use i386 for PC type 386 boxes. (Compaq, etc.)
  # SUN3, SUN4, SUN386i, VAX, SONY, CONVEX, HP, HP9KS300, i386, NeXT, AIX,
  # ATT3B, ATT386
! TARGET = SUN3
  
  # The name of the target operating system.  There isn't such a big
  # difference between SUNOS3 and Bsd.  But there might be in the future.
  # SUNOS3, SUNOS4, SYSV, Bsd, HPUX, UNIXPC
! OS = SUNOS4
  
  # You only need this if you are hacking the shell in a location
  # that doesn't do enough backups, or does a poor job.  In that
--- 45,56 ----
  # Use i386 for PC type 386 boxes. (Compaq, etc.)
  # SUN3, SUN4, SUN386i, VAX, SONY, CONVEX, HP, HP9KS300, i386, NeXT, AIX,
  # ATT3B, ATT386
! TARGET = i386
  
  # The name of the target operating system.  There isn't such a big
  # difference between SUNOS3 and Bsd.  But there might be in the future.
  # SUNOS3, SUNOS4, SYSV, Bsd, HPUX, UNIXPC
! OS = XENIX
  
  # You only need this if you are hacking the shell in a location
  # that doesn't do enough backups, or does a poor job.  In that
***************
*** 72,81 ****
  # HP-UX compilation requires the BSD library.
  #LOCAL_LIBS = -lBSD
  
! # Xenix requires -ldir -lx.  It is also required in the readline Makefile.
! #LOCAL_LIBS = -ldir -lx
  
! GCC_SUNOS4_FLAG = -Bstatic
  DEBUG_FLAGS = $(PROFILE_FLAGS) -g $(GCC_SUNOS4_FLAG)
  LDFLAGS	= $(DEBUG_FLAGS)
  CFLAGS	= $(DEBUG_FLAGS) -D${TARGET} -DTARGET=${TARGET} -D${OS}
--- 72,84 ----
  # HP-UX compilation requires the BSD library.
  #LOCAL_LIBS = -lBSD
  
! # For SCO Xenix: -lx contains compatibility stuff like directory
! # functions.  Change the pathname /u/lib/alloca.o as necessary
! # to point to alloca.o compiled from alloca.s in the GNU Emacs 
! # distribution
! LOCAL_LIBS = /u/lib/alloca.o -lx 
  
! #GCC_SUNOS4_FLAG = -Bstatic
  DEBUG_FLAGS = $(PROFILE_FLAGS) -g $(GCC_SUNOS4_FLAG)
  LDFLAGS	= $(DEBUG_FLAGS)
  CFLAGS	= $(DEBUG_FLAGS) -D${TARGET} -DTARGET=${TARGET} -D${OS}
***************
*** 82,92 ****
  CPPFLAGS= -I$(LIBSRC)
  
  # If you don't have Bison use "yacc".  Otherwise use "bison -y".
! #BISON = yacc
! BISON = bison -y
  
  # If you don't have Gcc use cc.
! CC = gcc -traditional
  
  ####################################################################
  
--- 85,96 ----
  CPPFLAGS= -I$(LIBSRC)
  
  # If you don't have Bison use "yacc".  Otherwise use "bison -y".
! BISON = yacc
! #BISON = bison -y
  
  # If you don't have Gcc use cc.
! #CC = gcc -traditional
! CC = cc
  
  ####################################################################
  
***************
*** 129,135 ****
  
  # If your system doesn't have a sys_siglist, then define SIGLIST
  # as siglist.o
! #SIGLIST = siglist.o
  
  RM = rm -f
  AR = ar
--- 133,139 ----
  
  # If your system doesn't have a sys_siglist, then define SIGLIST
  # as siglist.o
! SIGLIST = siglist.o
  
  RM = rm -f
  AR = ar
***************
*** 139,145 ****
  # We would like to use GNU's termcap library.  Where is it?
  # If you don't have -ltermcap, you might try -lcurses.
  #TERMCAP = -ltermcap
! TERMCAP=/usr/lib/libtermcap.a
  READLINE= ./readline/libreadline.a
  
  # The source code for the support libraries.
--- 143,150 ----
  # We would like to use GNU's termcap library.  Where is it?
  # If you don't have -ltermcap, you might try -lcurses.
  #TERMCAP = -ltermcap
! #TERMCAP=/usr/lib/libtermcap.a
! TERMCAP=/lib/386/Slibtermcap.a
  READLINE= ./readline/libreadline.a
  
  # The source code for the support libraries.
diff -c bash-1.04/builtins.c bash/builtins.c
*** bash-1.04/builtins.c	Tue Oct 31 02:06:14 1989
--- bash/builtins.c	Sat Dec  9 23:39:50 1989
***************
*** 21,31 ****
  #include <stdio.h>
  #include <sys/param.h>
  
- #ifndef SYSV
- #include <sys/time.h>
- #include <sys/resource.h>
- #endif
- 
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <sys/file.h>
--- 21,26 ----
***************
*** 36,41 ****
--- 31,41 ----
  #include "flags.h"
  #include <readline/history.h>
  
+ #ifndef SYSV /* don't test SYSV until after shell.h has been included */
+ #include <sys/time.h>
+ #include <sys/resource.h>
+ #endif
+ 
  #ifdef JOB_CONTROL
  #include "jobs.h"
  #endif
***************
*** 1228,1233 ****
--- 1228,1234 ----
  logout_builtin (list)
       WORD_LIST *list;
  {
+   extern int interactive;
    if (!login_shell && interactive)
      {
        report_error ("Not login shell: use `exit' or `bye'");
***************
*** 2384,2389 ****
--- 2385,2391 ----
  {
    extern int variable_context;
    int flags_on = 0, flags_off = 0;
+   extern int array_needs_making;
  
    while (list)
      {
diff -c bash-1.04/config.h bash/config.h
*** bash-1.04/config.h	Thu Sep 21 22:41:17 1989
--- bash/config.h	Sat Dec  9 22:19:05 1989
***************
*** 21,27 ****
  #define hpux
  #endif
  
! #if defined (hpux) || defined (UNIXPC)
  #define SYSV
  #endif
  
--- 21,27 ----
  #define hpux
  #endif
  
! #if defined (hpux) || defined (UNIXPC) || defined(XENIX)
  #define SYSV
  #endif
  
***************
*** 66,72 ****
  
  /* Define NO_WAIT_H if your system doesn't seem to have sys/wait.h.
     This is true for HPUX and ALTOS. */
! #if defined (HPUX) || defined (ALTOS)
  #define NO_WAIT_H
  #endif
  
--- 66,72 ----
  
  /* Define NO_WAIT_H if your system doesn't seem to have sys/wait.h.
     This is true for HPUX and ALTOS. */
! #if defined (HPUX) || defined (ALTOS) || defined(XENIX)
  #define NO_WAIT_H
  #endif
  
diff -c bash-1.04/glob.c bash/glob.c
*** bash-1.04/glob.c	Sat Sep 23 02:35:45 1989
--- bash/glob.c	Sun Dec 10 00:00:18 1989
***************
*** 19,50 ****
     Unix programs use to perform this function.  I wrote this from scratch
     based on specifications for the pattern matching.  --RMS.  */
  
  #include <sys/types.h>
  
! #if	defined(USGr3) || defined(DIRENT)
  #include <dirent.h>
  #define direct dirent
  #define	D_NAMLEN(d) strlen((d)->d_name)
! #else	/* Not USGr3 and not DIRENT.  */
  #define D_NAMLEN(d) ((d)->d_namlen)
! #	ifdef	USG
  #include "ndir.h"   /* Get ndir.h from the Emacs distribution.  */
! #	else	/* Not USG.  */
  #include <sys/dir.h>
! #	endif	/* USG.  */
! #endif	/* USGr3 or DIRENT.  */
  
! #ifdef USG
  #include <memory.h>
  #include <string.h>
  #define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
  #define rindex	strrchr
  
! #else /* not USG */
  #include <strings.h>
  
  extern void bcopy ();
! #endif /* not USG */
  
  #ifdef	__GNUC__
  #define	alloca(n)	__builtin_alloca (n)
--- 19,52 ----
     Unix programs use to perform this function.  I wrote this from scratch
     based on specifications for the pattern matching.  --RMS.  */
  
+ #include "config.h"
+ 
  #include <sys/types.h>
  
! #if	defined(SYSVr3) || defined(DIRENT)
  #include <dirent.h>
  #define direct dirent
  #define	D_NAMLEN(d) strlen((d)->d_name)
! #else	/* Not SYSVr3 and not DIRENT.  */
  #define D_NAMLEN(d) ((d)->d_namlen)
! #	ifdef	SYSV
  #include "ndir.h"   /* Get ndir.h from the Emacs distribution.  */
! #	else	/* Not SYSV.  */
  #include <sys/dir.h>
! #	endif	/* SYSV.  */
! #endif	/* SYSVr3 or DIRENT.  */
  
! #ifdef SYSV
  #include <memory.h>
  #include <string.h>
  #define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
  #define rindex	strrchr
  
! #else /* not SYSV */
  #include <strings.h>
  
  extern void bcopy ();
! #endif /* not SYSV */
  
  #ifdef	__GNUC__
  #define	alloca(n)	__builtin_alloca (n)
diff -c bash-1.04/jobs.h bash/jobs.h
*** bash-1.04/jobs.h	Mon Aug 21 01:29:49 1989
--- bash/jobs.h	Sun Dec 10 16:40:20 1989
***************
*** 8,13 ****
--- 8,56 ----
  
  #if defined (i386) || defined (ATT3B) || defined (ATT386)
  
+ #ifdef XENIX
+ /* This should work with any compiler that allocates bitfields */
+ /* starting with the LSB, like God intended them to. */
+ 
+ union wait
+   {
+     int	w_status;		/* used in syscall */
+ 
+     /* Terminated process status. */
+     struct
+       {
+ 	unsigned short
+ 	  w_Termsig  : 7,	/* termination signal */
+ 	  w_Coredump : 1,	/* core dump indicator */
+ 	  w_Retcode  : 8,	/* exit code if w_termsig==0 */
+ 	  w_Fill1    : 16;	/* high 16 bits unused */
+       } w_T;
+ 
+     /* Stopped process status.  Returned
+        only for traced children unless requested
+        with the WUNTRACED option bit. */
+     struct
+       {
+ 	unsigned short
+ 	  w_Stopval : 8,	/* == W_STOPPED if stopped */
+ 	  w_Stopsig : 8,	/* actually zero on XENIX */
+ 	  w_Fill2   : 16;	/* high 16 bits unused */
+       } 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))
+ 
+ #else /* XENIX */
+ 
  union wait {
    struct {
      unsigned char low;
***************
*** 27,32 ****
--- 70,76 ----
  #define WIFSTOPPED(wstat) ((wstat).bytes.low == 0177)
  #define WIFTERMINATED(wstat) ((wstat).bytes.high == 0)
  
+ #endif /* XENIX */
  #else  /* i386 || ATT3B || ATT386 */
  
  #ifdef NO_WAIT_H
diff -c bash-1.04/newversion.c bash/newversion.c
*** bash-1.04/newversion.c	Tue Oct 31 16:48:54 1989
--- bash/newversion.c	Sat Dec  9 20:58:45 1989
***************
*** 101,107 ****
      distver = distver + 0.01;
  
    file = must_open ("newversion.h", "w");
!   fprintf (file, "%s%.2f\n%s%d\n","\
  /* Version control for the shell.  This file gets changed when you say\n\
     `make newversion' to the Makefile.  It is created by newversion.aux. */\n\
  \n\
--- 101,107 ----
      distver = distver + 0.01;
  
    file = must_open ("newversion.h", "w");
!   fprintf (file, "%s\"%.2f\"\n%s%d\n","\
  /* Version control for the shell.  This file gets changed when you say\n\
     `make newversion' to the Makefile.  It is created by newversion.aux. */\n\
  \n\
diff -c bash-1.04/nojobs.c bash/nojobs.c
*** bash-1.04/nojobs.c	Wed Nov  1 19:26:13 1989
--- bash/nojobs.c	Sat Dec  9 23:25:31 1989
***************
*** 58,63 ****
--- 58,64 ----
   */
  initialize_jobs ()
  {
+   get_tty_state ();
  }
  
  /*
***************
*** 149,155 ****
  wait_for (pid)
       int pid;
  {
!   int got_pid, return_val, oldmask;
    union wait status;
  #ifndef SYSV
    SigHandler *old_int, *old_quit;
--- 150,161 ----
  wait_for (pid)
       int pid;
  {
!   int got_pid, return_val;
! #ifdef XENIX
!  SigHandler *oldmask;
! #else
!  int oldmask;
! #endif
    union wait status;
  #ifndef SYSV
    SigHandler *old_int, *old_quit;
***************
*** 156,162 ****
--- 162,172 ----
  #endif
  
  #ifdef SYSV
+ #ifdef XENIX
+   oldmask = signal (SIGINT, SIG_IGN);
+ #else
    oldmask = sigignore (SIGINT);
+ #endif
  #else
    oldmask = sigblock (sigmask (SIGINT));
  #endif
***************
*** 174,180 ****
--- 184,194 ----
  
  
  #ifdef SYSV
+ #ifdef XENIX
+   signal (SIGINT, oldmask);
+ #else
    sigrelse (oldmask);
+ #endif
  #else
    sigsetmask (oldmask);
  #endif
***************
*** 190,197 ****
  	fprintf (stderr, " (core dumped)");
        fprintf (stderr, "\n");
        return_val = status.w_termsig + 128;
-       get_tty_state ();
      }
    return (return_val);
  }
  
--- 204,217 ----
  	fprintf (stderr, " (core dumped)");
        fprintf (stderr, "\n");
        return_val = status.w_termsig + 128;
      }
+   /* If the command did not exit cleanly, 
+      then reset the tty state back to what it
+      was before this command. */
+   if (status.w_termsig != 0)
+     set_tty_state ();
+   else
+     get_tty_state ();
    return (return_val);
  }
  
diff -c bash-1.04/shell.c bash/shell.c
*** bash-1.04/shell.c	Sat Nov  4 15:34:08 1989
--- bash/shell.c	Sat Dec  9 22:32:09 1989
***************
*** 45,58 ****
  #include <sys/stat.h>
  #include <pwd.h>
  
- #ifdef SYSV
- struct passwd *getpwuid();
- #endif
- 
  #include "shell.h"
  #include "flags.h"
  
! extern float dist_version;
  extern int build_version;
  
  extern int yydebug;
--- 45,58 ----
  #include <sys/stat.h>
  #include <pwd.h>
  
  #include "shell.h"
  #include "flags.h"
  
! #ifdef SYSV /* don't test SYSV before shell.h has been included */
! struct passwd *getpwuid();
! #endif
! 
! extern char *dist_version;
  extern int build_version;
  
  extern int yydebug;
***************
*** 669,675 ****
--- 669,679 ----
  {
  
    /* Line buffer output for stderr. */
+ #ifdef XENIX /* The Xenix setvbuf is buggy */
+   setvbuf (stderr, _IOLBF, (char *)NULL, BUFSIZ);
+ #else
    setvbuf (stderr, (char *)NULL, _IOLBF, BUFSIZ);
+ #endif
  
    /* The initialization of the basic underlying signal handlers must
       happen before we initialize_traps ().  */
***************
*** 915,921 ****
  \n\
  since he is the current maintainer of this version of the shell.\n\
  \n\
! This is %s (invoked as `%s'), version %.2f.%d, on host %s, used by %s.\n\
  This shell is %sinteractive, and it is %sa login shell.\n\
  \n\
  The host is a %s running %s.\n\
--- 919,925 ----
  \n\
  since he is the current maintainer of this version of the shell.\n\
  \n\
! This is %s (invoked as `%s'), version %s.%d, on host %s, used by %s.\n\
  This shell is %sinteractive, and it is %sa login shell.\n\
  \n\
  The host is a %s running %s.\n\
***************
*** 966,971 ****
    extern char *shell_name;
    extern int version;
  
!   printf ("GNU %s, version %.2f.%d\n", shell_name,
  	  dist_version, build_version);
  }
--- 970,975 ----
    extern char *shell_name;
    extern int version;
  
!   printf ("GNU %s, version %s.%d\n", shell_name,
  	  dist_version, build_version);
  }
diff -c bash-1.04/variables.c bash/variables.c
*** bash-1.04/variables.c	Sun Sep 17 22:02:43 1989
--- bash/variables.c	Thu Nov 23 21:38:28 1989
***************
*** 216,225 ****
    /* Make a variable called BASH_VERSION which contains the version info. */
    {
      char tt[12];
!     extern float dist_version;
      extern int build_version;
  
!     sprintf (tt, "%.2f.%d", dist_version, build_version);
      bind_variable ("BASH_VERSION", tt);
    }
  
--- 216,225 ----
    /* Make a variable called BASH_VERSION which contains the version info. */
    {
      char tt[12];
!     extern char *dist_version;
      extern int build_version;
  
!     sprintf (tt, "%s.%d", dist_version, build_version);
      bind_variable ("BASH_VERSION", tt);
    }
  
diff -c bash-1.04/version.c bash/version.c
*** bash-1.04/version.c	Fri Aug 25 09:02:44 1989
--- bash/version.c	Sat Dec  9 21:07:50 1989
***************
*** 20,24 ****
  
  #include "version.h"
  
! float dist_version = DISTVERSION;
  int build_version = BUILDVERSION;
--- 20,24 ----
  
  #include "version.h"
  
! char *dist_version = DISTVERSION;
  int build_version = BUILDVERSION;
================================ Cut here ================================
Technical Details
Message-ID: <8912101623.AA02875@robin.hut.fi>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!tut.cis.ohio-state.edu!ROBIN.HUT.FI!gson

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!tut.cis.ohio-state.edu!ROBIN.HUT.FI!gson
From: gson@ROBIN.HUT.FI
Newsgroups: gnu.bash.bug
Subject: Bash 1.04 Xenix diffs + general bug fixes
Message-ID: <8912101623.AA02875@robin.hut.fi>
Date: 10 Dec 89 16:23:31 GMT
Sender: daemon@tut.cis.ohio-state.edu
Distribution: gnu
Organization: GNUs Not Usenet
Lines: 682