Article View: gnu.bash.bug
Article #824Bash 1.04 Xenix diffs + general bug fixes
From: gson
Date: Sun, 10 Dec 1989 16:23
Date: Sun, 10 Dec 1989 16:23
682 lines
20966 bytes
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!gsonShow 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