Path: 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 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 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 #include - #ifndef SYSV - #include - #include - #endif - #include #include #include --- 21,26 ---- *************** *** 36,41 **** --- 31,41 ---- #include "flags.h" #include + #ifndef SYSV /* don't test SYSV until after shell.h has been included */ + #include + #include + #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 ! #if defined(USGr3) || defined(DIRENT) #include #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 ! # endif /* USG. */ ! #endif /* USGr3 or DIRENT. */ ! #ifdef USG #include #include #define bcopy(s, d, n) ((void) memcpy ((d), (s), (n))) #define rindex strrchr ! #else /* not USG */ #include 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 ! #if defined(SYSVr3) || defined(DIRENT) #include #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 ! # endif /* SYSV. */ ! #endif /* SYSVr3 or DIRENT. */ ! #ifdef SYSV #include #include #define bcopy(s, d, n) ((void) memcpy ((d), (s), (n))) #define rindex strrchr ! #else /* not SYSV */ #include 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 #include - #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 #include #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 ================================