[gnu.emacs.bug] Portability bugs in 18-55 gnu-emacs

mac@rhea.mit.edu (Mike McNamara) (08/30/89)

	This mail contains NO specific patches for support of
gnu-emacs on the Ardent Titan; INSTEAD, these are all patches to
gnu-emacs that fix bugs in gnu-emacs that become evident when emacs is
compiled on the Ardent Titan. 

-----
	You may recall that a few months ago, I sent to you diffs to
bring emacs-18.54 up on an Ardent Titan. RMS suggested that I re-do
the port to the Titan, this time as a System V box. 
	(The Ardent titan *does* support bsd4.3 at the system call
level, but its directory structure, man page layout, lineprinter, and
so on are all system V based.)
	Well I got busy building new machines that are faster,
cheaper, easier to use, and all that, and while I promised I would re
do the port and send it in, I did not get around to it.  

	The FSF has since released 18.55 gnu-emacs, and so I decided
to take a day and port that to the Titan, this time trying to minimize
the changes to emacs files.
-----

	I tried to make gnu-emacs work on the Titan with & without the
following defines:

	HAVE_TERMIO
	INTERRUPT_INPUT
	HAVE_TIMEVAL
	
HAVE_TERMIO was no problem; the titan supports both termcap &
terminfo.

INTERRUPT_INPUT was a bit harder, as emacs is not consistant regarding
SIGIO & FIONREAD.  Details & patchs follow.

HAVE_TIMEVAL was a bit harder than that; it seems that emacs source is
not very consistant about where to get the include file that describes
struct timeval.

Further, there is a squirrelly bug with SetBfp which you might recall
exchanging mail with me about.  I here include an explanation & a
patch for that problem.

Following is a merged Changlog & patch files for the GENERIC bugs I
found in emacs.  Any questions, comments, whatever, feel free to send
me mail at mac@ardent.com

Later mail contains an m-titan.h and two titan specific changes to
source files which work around titan specific problems.
Mon Aug 28 17:40:42 1989  Mike McNamara  (mac at rhea.ardent.com)

	* (x11term.h) This file conditionally defines BLOCK_INPUT based on
	the existatance of SIGIO.  It should also check FIONREAD.
	Patch follows:

diff -cbr dist-18.55/src/x11term.h wrk-18.55/src/x11term.h
*** dist-18.55/src/x11term.h	Fri Aug 25 15:28:40 1989
--- wrk-18.55/src/x11term.h	Mon Aug 28 18:52:45 1989
***************
*** 12,21 ****
  #endif
  
  #define BLOCK_INPUT_DECLARE() int BLOCK_INPUT_mask
! #ifdef SIGIO
  #define BLOCK_INPUT() BLOCK_INPUT_mask = sigblock (sigmask (SIGIO))
  #define UNBLOCK_INPUT() sigsetmask (BLOCK_INPUT_mask)
! #else /* not SIGIO */
  #define BLOCK_INPUT()
  #define UNBLOCK_INPUT()
  #endif /* SIGIO */
--- 12,21 ----
  #endif
  
  #define BLOCK_INPUT_DECLARE() int BLOCK_INPUT_mask
! #if defined(SIGIO) && defined(FIONREAD)
  #define BLOCK_INPUT() BLOCK_INPUT_mask = sigblock (sigmask (SIGIO))
  #define UNBLOCK_INPUT() sigsetmask (BLOCK_INPUT_mask)
! #else /* not SIGIO && FIONREAD */
  #define BLOCK_INPUT()
  #define UNBLOCK_INPUT()
  #endif /* SIGIO */

	* (x11term.c, process.c) although USG, the titan defines timval
	in <sys/time.h> not <time.h>

	Fix: grab struct timeval from sys/time.h instead.

	It seems that in general, the inclusion of <time.h> versus
	<sys/time.h>, based on HAVE_TIMEVAL, is rather adhoc.  It seems
	that each file that tests HAVE_TIMEVAL (dispnew.c, fileio.c,
	process.c, sysdep.c & xfns.c) conditionally includes
	<{sys/,}time.h> differently.  This should be rationalized.
	
	For some machines, it seems that <sys/time> is used in some
	places, but <time.h> is used in others. Perhaps what we need is to
	add the following to m-*.h

	/* Define where your system defines the structure timeval, as returned 
	   by gettimeofday.  If you don't define HAVE_TIMEVAL, than this does
	   not matter */
	#define TIMEVAL_INCLUDE <sys/time.h> /* Some system V machines */
	/* #define TIMEVAL_INCLUDE <time.h>  /* BSD systems, & some system V */
	
	and then change dispnew.c, fileio.c, process.c,sysdep.c & xfns.c to

	#ifdef HAVE_TIMEVAL
	#include TIMEVAL_INCLUDE
	#endif

	But of course, I include here just a patch to make the titan work.
	Patch follows:
diff -cbr dist-18.55/src/x11term.c wrk-18.55/src/x11term.c
*** dist-18.55/src/x11term.c	Mon Aug 28 10:20:17 1989
--- wrk-18.55/src/x11term.c	Mon Aug 28 18:42:12 1989
***************
*** 71,77 ****
  #include "x11term.h"
  
  #ifdef USG
! #ifdef IRIS_4D
  #include <sys/time.h>
  #else
  #include <time.h>
--- 71,77 ----
  #include "x11term.h"
  
  #ifdef USG
! #if defined(IRIS_4D) || defined(titan)
  #include <sys/time.h>
  #else
  #include <time.h>

diff -cbr dist-18.55/src/process.c wrk-18.55/src/process.c
*** dist-18.55/src/process.c	Mon Aug 28 10:20:09 1989
--- wrk-18.55/src/process.c	Tue Aug 29 14:07:03 1989
***************
*** 63,69 ****
  
  #else /* not IRIS, not UNIPLUS */
  #ifdef HAVE_TIMEVAL
! #if defined(USG) && !defined(IBMRTAIX)
  #include <time.h>
  #else /* IBMRTAIX or not USG */
  #include <sys/time.h>
--- 63,69 ----
  
  #else /* not IRIS, not UNIPLUS */
  #ifdef HAVE_TIMEVAL
! #if defined(USG) && !defined(IBMRTAIX) && !defined(titan)
  #include <time.h>
  #else /* IBMRTAIX or not USG */
  #include <sys/time.h>


	* (dispnew.c) dispnew conditionally calls gobble_input; The
	condition it tests is the existance of SIGIO.
	  keyboard.c conditionally defines function gobble_input; the condition it
	tests is the existance of SIGIO &FIONREAD.

	Fix: conditionally call gobble_input from dispnew based on the
	existance of both SIGIO & FINOREAD.
	Patch follows:
diff -cbr dist-18.55/src/dispnew.c wrk-18.55/src/dispnew.c
*** dist-18.55/src/dispnew.c	Mon Aug 28 10:19:57 1989
--- wrk-18.55/src/dispnew.c	Mon Aug 28 15:38:56 1989
***************
*** 1351,1359 ****
--- 1351,1363 ----
    if (XINT (n) > 0)
      {
  #ifdef subprocesses
+ /* We are unable to use interrupts if FIONREAD is not available,
+ 	so don't call gobble_input (or home?) without it */
+ #ifdef FIONREAD
  #ifdef SIGIO
        gobble_input ();
  #endif				/* SIGIO */
+ #endif				/* FIONREAD */
        wait_reading_process_input (XINT (n), 1, 1);
  #else				/* no subprocesses */
        immediate_quit = 1;

	* (buffer.c) SetBfp's logic wrt selected_window is broken; only on
	machines that have high bits set in data addresses 
	(DATA_SEG_BITS != 0), AND that DATA_SEG_BITS it self is not a
	vaild address.

	For example, on the Ardent Titan, the data region starts at
	0x10003000. Hence DATA_SEG_BITS is 0x10000000; however,
	DATA_SEG_BITS itself is not a valid address. (There is a memory
	mapped vector processor at 0x10000000 - 0x10002fff)
	
	The bug: Basically, SetBfp assigns w XWINDOW(selected_window).
	As selected_window starts as 0x0, this results in the w getting
	the value 0 | DATA_SEG_BITS.  SetBfp then tests this values
	against 0, to see if there exists a selected_window.  On most
	machines, DATA_SEG_BITS is zero, and the bug in SetBfp is
	unexposed and harmless. 
	
	On most machines where DATA_SEG_BITS != 0, the start of data 
	== DATA_SEG_BITS.  Hence here the code incorrectly, yet not
	fatally, dereferences some random data at the start of the 
	data region.  (I note that in SteBfp there is some Vcheck_symbol
	checkage that is commented to check for a bug that clobbers
	paragraph-start. Perhaps that is related to this bug?)

	On at least one machine (the Ardent Titan) the address
	DATA_SEG_BITS is an illegal address, and dereferencing it
	results in an FPE (random poking at vector units is discouraged)

	To fix the bug, change buffer.c, line 816 from
	if (w)
	to
	if (selected_window)

	Patch follows:
diff -cbr dist-18.55/src/buffer.c wrk-18.55/src/buffer.c
*** dist-18.55/src/buffer.c	Mon Aug 28 10:19:54 1989
--- wrk-18.55/src/buffer.c	Mon Aug 28 17:13:57 1989
***************
*** 813,819 ****
    if (c == p)
      return;
  
!   if (w)
      swb = NULL (selected_window) ? 0 : XBUFFER (w->buffer);
  
    if (p && NULL (p->name))
--- 813,819 ----
    if (c == p)
      return;
  
!   if (selected_window)
      swb = NULL (selected_window) ? 0 : XBUFFER (w->buffer);
  
    if (p && NULL (p->name))


	* (sysdep.c) sysdep.c needs to define TEXT_END and DATA_END before
	it takes their addresses, for the case etext & edata are named
	something else.

	Fix: add extern int TEXT_END to the conditionally compiled section
	of end_text that would return this.  Similarly for DATA_END.
	Patch follows:
diff -cbr dist-18.55/src/sysdep.c wrk-18.55/src/sysdep.c
*** dist-18.55/src/sysdep.c	Mon Aug 28 10:20:13 1989
--- wrk-18.55/src/sysdep.c	Mon Aug 28 15:47:42 1989
***************
*** 1347,1352 ****
--- 1347,1353 ----
  end_of_text ()
  {
  #ifdef TEXT_END
+   extern TEXT_END;
    return ((char *) TEXT_END);
  #else
    extern int etext;
***************
*** 1363,1368 ****
--- 1364,1370 ----
  end_of_data ()
  {
  #ifdef DATA_END
+   extern int DATA_END;
    return ((char *) DATA_END);
  #else
    extern int edata;

	* (x11term.c) XTFlash unconditionally assumes timeval exists.
	(doesn't check HAVE_TIMEVAL)  I here gave up and just defined 
	HAVE_TIMEVAL, as the titan does have it.