Unofficial patch for GNU Emacs 18.54 etc... System V

Piercarlo Grandi pcg at aber-cs.UUCP
Sat Jan 6 04:49:31 AEST 1990


Here are some patches to GNU Emacs 18.54, mainly for better System V
comfort. Also some possible speedup on gap moves.

I advise you to have a look at these patches, so that you know which flags
to add to your config.h file...

	For example, for gap moves, #define BSTRING and then if you have
	bcopy(3) you can set both LTOR and RTOL to 1; if you have memcpy(3),
	you can usually set LTOR to 1 and RTOL to 0.

These patches are for running GNU Emacs 18.54 on a System V.3.2 machine, in
my case specifically ESIX Rev. A. They contain J.  Van Artsdalen patches for
better COFF support (including shared libraries) when undumping, some
patches to take advantage of either BSD compatible ptys or stream based
ptys, for full support of shell windows, and some non System V specific
patches to speed up gap movements.

I am omitting some other patches I find useful, for example to some headers
to comment properly preprocessor lines, and to the ymakefile and the list
sources; I have moved all the [ms]-*.h files into a config directory, and
all elisp files not included in the image in a ../lisplib directory, and
removed the mechanism that causes on every link a different name executable
and doc file to be produced, and substantially trimmed the list of elisp
files that go in the dumped image. Core, disc, and CPU are scarce on my
small home machine -- I have only 4 MIPS with few MBytes of RAM and 120
MBytes of disc... (heavvvy irony intended here).

Here is a list of changes:

buffer.c

	The default initial gap is enlarged.

emacs.c

	Some support added for COFF shared libraries.

insdel.c

	To move text around the gap we can now use the block move
	library routines, if it is worthwhile, and if it is safe.
	The default gap size has also been substantially increased.

process.c

	Some long needed simplification has been made in the pty
	code. It is still a mess. I have added support for
	stream based ptys (which are common to all System Vs,
	not just the IRIS), and inserted a couple of other
	minor but at times vital patches, some from the net.

sysdep.c

	Here are again some minor but useful patches, and a
	"full" simulation of select(2) based on poll(2) (which
	has not been tested really, and in any case only works
	if all ttys, ptys, etc... are stream based, as they
	*ought* to be); the original partial select(2)
	simulation has also been patched a little bit.

unexec.c

	The main bulk of J. Van Artsdalen improved COFF support.


===================================================================
RCS file: buffer.c,v
retrieving revision 18.54
diff -c -r18.54 buffer.c
*** /tmp/,RCSt1a13347	Thu Jan  4 14:18:14 1990
--- buffer.c	Fri Dec 29 15:26:49 1989
***************
*** 170,176 ****
    b = (struct buffer *) malloc (sizeof (struct buffer));
    if (!b) memory_full ();
  
!   data = (unsigned char *) malloc (b->text.gap = 20);
    if (!data) memory_full ();
    b->text.p1 = data - 1;
    b->text.p2 = data - 1 + b->text.gap;
--- 170,182 ----
    b = (struct buffer *) malloc (sizeof (struct buffer));
    if (!b) memory_full ();
  
!   /*
!     We want the initial size of the gap to be large enough for smallish
!     buffers, e.g. help buffers, minibuffers, etc..., up to a few lines
!     of the screen. A typical screen is about 2k characters.
!   */
!     
!   data = (unsigned char *) malloc (b->text.gap = 512);
    if (!data) memory_full ();
    b->text.p1 = data - 1;
    b->text.p2 = data - 1 + b->text.gap;
===================================================================
RCS file: emacs.c,v
retrieving revision 18.54
diff -c -r18.54 emacs.c
*** /tmp/,RCSt1a13347	Thu Jan  4 14:18:16 1990
--- emacs.c	Thu Dec 28 18:22:26 1989
***************
*** 81,86 ****
--- 81,88 ----
  int xargc;
  #endif /* HAVE_X_WINDOWS */
  
+ unsigned int bss_end = 0;
+ 
  /* Nonzero means running Emacs without interactive terminal.  */
  
  int noninteractive;
***************
*** 202,207 ****
--- 204,214 ----
  #endif /* SHAREABLE_LIB_BUG */
  #endif /* LINK_CRTL_SHARE */
  #endif /* VMS */
+ 
+ #ifdef USG_SHARED_LIBRARIES
+   if (bss_end)
+     brk(bss_end);
+ #endif
  
    clearerr (stdin);
  
===================================================================
RCS file: insdel.c,v
retrieving revision 18.54
diff -c -r18.54 insdel.c
*** /tmp/,RCSt1a13347	Thu Jan  4 14:18:18 1990
--- insdel.c	Fri Dec 29 18:12:02 1989
***************
*** 24,29 ****
--- 24,44 ----
  #include "buffer.h"
  #include "window.h"
  
+ #ifdef BSTRING
+ # ifdef BSTRING_LTOR
+ #   undef BSTRING_LTOR
+ #   define BSTRING_LTOR 1
+ # else
+ #   define BSTRING_LTOR 0
+ # endif
+ # ifdef BSTRING_RTOL
+ #   undef BSTRING_RTOL
+ #   define BSTRING_RTOL 1
+ # else
+ #   define BSTRING_RTOL 0
+ # endif
+ #endif
+ 
  /* Move gap to position `pos'.
     Note that this can quit!  */
  
***************
*** 33,38 ****
--- 48,58 ----
    if (bf_p2 != bf_gap + bf_p1)
      abort ();
  
+   /*
+     if pos == bs_s1 then the gap does not need moving at all. Remember
+     that bs_s1 points to 1 *below* the real start of the gap.
+   */
+ 
    if (pos <= bf_s1)
      gap_left (pos);
    else if (pos > bf_s1 + 1)
***************
*** 86,91 ****
--- 106,121 ----
        if (i > 32000)
  	i = 32000;
        new_s1 -= i;
+ #if defined(BSTRING)
+       /*
+         We are moving the gap to the left; this means moving
+ 	memory to the right (from <= to), and overlaps are safe
+ 	if we copy from right to left.
+       */
+       if (i >= 32 && (BSTRING_RTOL || /* no overlap */ from <= to-i))
+ 	from -= i, to -= i, (void) bcopy (from,to,i);
+       else
+ #endif
        while (--i >= 0)
  	*--to = *--from;
      }
***************
*** 146,151 ****
--- 176,192 ----
        if (i > 32000)
  	i = 32000;
        new_s1 += i;
+ 
+ #ifdef BSTRING
+       /*
+         We are moving the gap to the right; this means moving
+ 	memory to the left (to <= from), and overlaps are safe
+ 	if we copy from left to right.
+       */
+       if (i >= 32 && (BSTRING_LTOR || /* no overlap */ to+i <= from))
+ 	(void) bcopy (from,to,i), from += i, to += i;
+       else
+ #endif
        while (--i >= 0)
  	*to++ = *from++;
      }
***************
*** 204,210 ****
    if (bf_gap >= k)
      return;
  
!   k += 2000;			/* Get more than just enough */
  
    p1 = (unsigned char *) realloc (bf_p1 + 1, bf_s1 + bf_s2 + k);
    if (p1 == 0)
--- 245,251 ----
    if (bf_gap >= k)
      return;
  
!   k += 16000;			/* Get more than just enough */
  
    p1 = (unsigned char *) realloc (bf_p1 + 1, bf_s1 + bf_s2 + k);
    if (p1 == 0)
===================================================================
RCS file: process.c,v
retrieving revision 18.54
diff -c -r18.54 process.c
*** /tmp/,RCSt1a13347	Thu Jan  4 14:18:23 1990
--- process.c	Thu Dec 28 18:22:33 1989
***************
*** 42,78 ****
  #if defined(BSD) || defined(STRIDE)
  #include <sys/ioctl.h>
  #endif /* BSD or STRIDE */
  #ifdef USG
  #include <termio.h>
  #include <fcntl.h>
  #endif /* USG */
  
! #ifdef IRIS
! #include <sys/sysmacros.h>	/* for "minor" */
! #include <sys/time.h>
  #else
! #ifdef UNIPLUS
! #include <sys/time.h>
! 
! #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>
! #endif /* IBMRTAIX or not USG */
! #endif /* HAVE_TIMEVAL */
! 
! #endif /* not UNIPLUS */
  #endif /* not IRIS */
  
  #if defined (HPUX) && defined (HAVE_PTYS)
! #include <sys/ptyio.h>
  #endif
  
  #ifdef SYSV_PTYS
! #include <sys/tty.h>
! #include <sys/pty.h>
  #endif
  
  #undef NULL
--- 42,88 ----
  #if defined(BSD) || defined(STRIDE)
  #include <sys/ioctl.h>
  #endif /* BSD or STRIDE */
+ 
  #ifdef USG
  #include <termio.h>
  #include <fcntl.h>
  #endif /* USG */
  
! #if defined(IRIS) || defined(STREAM_PTYS)
! # include <sys/sysmacros.h>	/* for "minor" */
! # include <sys/time.h>
  #else
! # ifdef UNIPLUS
! #  include <sys/time.h>
! # else /* not IRIS, not UNIPLUS */
! #  ifdef HAVE_TIMEVAL
! #   if defined(USG) && !defined(IBMRTAIX) && !defined(i386)
! #    include <time.h>
! #   else /* IBMRTAIX or not USG */
! #    include <sys/time.h>
! #   endif /* IBMRTAIX or not USG */
! #  endif /* HAVE_TIMEVAL */
! # endif /* not UNIPLUS */
  #endif /* not IRIS */
  
  #if defined (HPUX) && defined (HAVE_PTYS)
! # include <sys/ptyio.h>
  #endif
  
  #ifdef SYSV_PTYS
! # include <sys/stream.h>
! # include <sys/tty.h>
! # include <sys/pty.h>
! #endif
! 
! #ifdef STREAM_PTYS
! #include <sys/stropts.h>
! #include <sys/stream.h>
! #include <sys/ptms.h>
! #define DID_REMOTE
! #define PTY_ITERATION		/* no iteration needed */
! #define PTY_NAME_SPRINTF	strcpy (ptyname, "/dev/ptmx");
! #define PTY_TTY_NAME_SPRINTF	sprintf (ptyname, "/dev/pts%03u", minor(stb.st_rdev));
  #endif
  
  #undef NULL
***************
*** 81,86 ****
--- 91,97 ----
  #include "buffer.h"
  #include "process.h"
  #include "termhooks.h"
+ #include "termopts.h"
  #include "commands.h"
  
  /* a process object is a network connection when its childp field is neither
***************
*** 114,130 ****
  #define WCOREDUMP(w) ((w&0200) != 0)
  #define WTERMSIG(w) (w & 0377)
  #else
! #ifdef BSD4_1
! #include <wait.h>
! #else
! #include <sys/wait.h>
! #endif /* not BSD 4.1 */
  #define WAITTYPE union wait
  #define WRETCODE(w) w.w_retcode
- #define WSTOPSIG(w) w.w_stopsig
  #define WCOREDUMP(w) w.w_coredump
! #define WTERMSIG(w) w.w_termsig
! #endif
  
  extern errno;
  extern sys_nerr;
--- 125,145 ----
  #define WCOREDUMP(w) ((w&0200) != 0)
  #define WTERMSIG(w) (w & 0377)
  #else
! # ifdef BSD4_1
! # include <wait.h>
! # else
! # include <sys/wait.h>
! # endif /* not BSD 4.1 */
  #define WAITTYPE union wait
  #define WRETCODE(w) w.w_retcode
  #define WCOREDUMP(w) w.w_coredump
! # ifndef WTERMSIG
! # define WTERMSIG(w) w.w_termsig
! # endif
! # ifndef WSTOPSIG
! # define WSTOPSIG(w) w.w_stopsig
! # endif
! #endif /* BSD or UNIPLUS or STRIDE */
  
  extern errno;
  extern sys_nerr;
***************
*** 176,184 ****
  Lisp_Object Vprocess_connection_type;
  
  #ifdef SKTPAIR
! #ifndef HAVE_SOCKETS
! #include <sys/socket.h>
! #endif
  #endif /* SKTPAIR */
  
  int  child_changed;		/* Flag when a child process has ceased
--- 191,199 ----
  Lisp_Object Vprocess_connection_type;
  
  #ifdef SKTPAIR
! # ifndef HAVE_SOCKETS
! # include <sys/socket.h>
! # endif
  #endif /* SKTPAIR */
  
  int  child_changed;		/* Flag when a child process has ceased
***************
*** 240,261 ****
  #ifdef RTU
  	sprintf (ptyname, "/dev/pty%x", i);
  #else
  	sprintf (ptyname, "/dev/pty%c%x", c, i);
  #endif /* not RTU */
  #endif /* not HPUX */
  #endif /* no PTY_NAME_SPRINTF */
  
  #ifndef IRIS
  	if (stat (ptyname, &stb) < 0)
  	  return 0;
  	*ptyv = open (ptyname, O_RDWR | O_NDELAY, 0);
  #else /* Unusual IRIS code */
!  	*ptyv = open ("/dev/ptc", O_RDWR | O_NDELAY, 0);
   	if (*ptyv < 0)
   	  return 0;
  	if (fstat (*ptyv, &stb) < 0)
  	  return 0;
  #endif /* IRIS */
  
  	if (*ptyv >= 0)
  	  {
--- 255,297 ----
  #ifdef RTU
  	sprintf (ptyname, "/dev/pty%x", i);
  #else
+ #ifdef IRIS
+ 	strcpy (ptyname, "/dev/ptc");
+ #else
  	sprintf (ptyname, "/dev/pty%c%x", c, i);
+ #endif /* not IRIS */
  #endif /* not RTU */
  #endif /* not HPUX */
  #endif /* no PTY_NAME_SPRINTF */
  
+ #ifdef STREAM_PTYS
+     {
+ 	int on = 1;
+ 
+  	*ptyv = open (ptyname, O_RDWR | O_NDELAY, 0);
+  	if (*ptyv < 0)
+  	  return 0;
+ 	if (fstat(*ptyv,&stb) < 0
+ 	    || ioctl(*ptyv,UNLKPT,&on) < 0
+ 	    || ioctl(*ptyv,I_PUSH,"ldterm") < 0)
+ 	{
+ 	    close(*ptyv);
+ 	    return 0;
+ 	}
+     }
+ #else
  #ifndef IRIS
  	if (stat (ptyname, &stb) < 0)
  	  return 0;
  	*ptyv = open (ptyname, O_RDWR | O_NDELAY, 0);
  #else /* Unusual IRIS code */
!  	*ptyv = open (ptyname, O_RDWR | O_NDELAY, 0);
   	if (*ptyv < 0)
   	  return 0;
  	if (fstat (*ptyv, &stb) < 0)
  	  return 0;
  #endif /* IRIS */
+ #endif /* STREAM_PTYS */
  
  	if (*ptyv >= 0)
  	  {
***************
*** 283,293 ****
--- 319,333 ----
  	    if (access (ptyname, 6) != 0)
  	      {
  		close (*ptyv);
+ #ifdef STREAM_PTYS
+ 		return 0;
+ #else
  #ifndef IRIS
  		continue;
  #else
  		return (0);
  #endif /* IRIS */
+ #endif /* STREAM_PTYS */
  	      }
  #endif /* not UNIPLUS */
  	    /*
***************
*** 349,354 ****
--- 389,402 ----
  	    }
  #endif
  #endif
+ #ifdef IBMRTAIX
+    /* On AIX, the parent gets SIGHUP when a pty attached child dies.  So, we */
+    /* ignore SIGHUP once we've started a child on a pty.  Note that this may */
+    /* cause EMACS not to die when it should, i.e., when its own controlling  */
+    /* tty goes away.  I've complained to the AIX developers, and they may    */
+    /* change this behavior, but I'm not going to hold my breath.             */
+ 	    signal (SIGHUP, SIG_IGN);
+ #endif
  	    return ptyname;
  	  }
        }
***************
*** 906,913 ****
    outchannel = inchannel;
    if (ptyname)
      {
! #ifndef IRIS
!       /* On the IRIS system it does not work to open
  	 the pty's tty here and then close and reopen it in the child.  */
        forkout = forkin = open (ptyname, O_RDWR, 0);
        if (forkin < 0)
--- 954,961 ----
    outchannel = inchannel;
    if (ptyname)
      {
! #ifndef USG
!       /* On USG systems it does not work to open
  	 the pty's tty here and then close and reopen it in the child.  */
        forkout = forkin = open (ptyname, O_RDWR, 0);
        if (forkin < 0)
***************
*** 986,996 ****
        {
  	int xforkin = forkin;
  	int xforkout = forkout;
  #ifdef HAVE_PTYS
  #ifdef TIOCNOTTY
  	/* In 4.3BSD, the TIOCSPGRP bug has been fixed, and now you
! 	   can do TIOCSPGRP only to the process's controlling tty.
! 	   We must make the pty terminal the controlling tty of the child.  */
  	if (ptyname)
  	  {
  	    /* I wonder: would just ioctl (0, TIOCNOTTY, 0) work here? 
--- 1034,1052 ----
        {
  	int xforkin = forkin;
  	int xforkout = forkout;
+ 
+ 	/* Make the pty be the controlling terminal of the process.  */
  #ifdef HAVE_PTYS
+ 	/* First, disconnect its current controlling terminal.  */
+ #ifdef USG
+ 	/* It's very important to call setpgrp() here and no time
+ 	   afterwards.  Otherwise, we lose our controlling tty which
+ 	   is set when we open the pty. */
+ 	setpgrp ();
+ #endif /* USG */
  #ifdef TIOCNOTTY
  	/* In 4.3BSD, the TIOCSPGRP bug has been fixed, and now you
! 	   can do TIOCSPGRP only to the process's controlling tty.  */
  	if (ptyname)
  	  {
  	    /* I wonder: would just ioctl (0, TIOCNOTTY, 0) work here? 
***************
*** 998,1008 ****
  	    int j = open ("/dev/tty", O_RDWR, 0);
  	    ioctl (j, TIOCNOTTY, 0);
  	    close (j);
  
! #if !defined (RTU) && !defined(UNIPLUS)
! #ifdef USG
! 	    setpgrp ();
! #endif
  	    /* I wonder if close (open (ptyname, ...)) would work?  */
  	    if (xforkin >= 0)
  	      close (xforkin);
--- 1054,1069 ----
  	    int j = open ("/dev/tty", O_RDWR, 0);
  	    ioctl (j, TIOCNOTTY, 0);
  	    close (j);
+ 	  }
+ #endif /* TIOCNOTTY */
  
! #if !defined (RTU) && !defined (UNIPLUS)
! /*** There is a suggestion that this ought to be a
!      conditional on TIOCSPGRP.  */
! 	/* Now close the pty (if we had it open) and reopen it.
! 	   This makes the pty the controlling terminal of the subprocess.  */
! 	if (ptyname)
! 	  {
  	    /* I wonder if close (open (ptyname, ...)) would work?  */
  	    if (xforkin >= 0)
  	      close (xforkin);
***************
*** 1010,1018 ****
  
  	    if (xforkin < 0)
  	      abort ();
- #endif /* not UNIPLUS and not RTU */
  	  }
! #endif /* TIOCNOTTY */
  #endif /* HAVE_PTYS */
  	child_setup_tty (xforkout);
  	child_setup (xforkin, xforkout, xforkout, new_argv, env);
--- 1071,1084 ----
  
  	    if (xforkin < 0)
  	      abort ();
  	  }
! #endif /* not UNIPLUS and not RTU */
! #ifdef IBMRTAIX
! 	/* On AIX, we've disabled SIGHUP above once we start a child on a pty.
! 	   Now reenable it in the child, so it will die when we want it to.  */
! 	if (ptyname)
! 	  signal (SIGHUP, SIG_DFL);
! #endif
  #endif /* HAVE_PTYS */
  	child_setup_tty (xforkout);
  	child_setup (xforkin, xforkout, xforkout, new_argv, env);
***************
*** 1116,1122 ****
      report_file_error ("error creating socket", Fcons (name, Qnil));
  
    if (connect (s, &address, sizeof address) == -1)
!     error ("Host \"%s\" not responding", XSTRING (host)->data);
  
    inch = s;
    outch = dup (s);
--- 1182,1191 ----
      report_file_error ("error creating socket", Fcons (name, Qnil));
  
    if (connect (s, &address, sizeof address) == -1)
!     {
!       close (s);
!       error ("Host \"%s\" not responding", XSTRING (host)->data);
!     }
  
    inch = s;
    outch = dup (s);
***************
*** 1398,1403 ****
--- 1467,1477 ----
  	  else
  	    error("select error: %s", sys_errlist[xerrno]);
  	}
+ #ifdef sun
+       else if (nfds > 0 && (Available & 1) && interrupt_input)
+ 	/* System sometimes fails to deliver SIGIO.  */
+ 	kill (getpid (), SIGIO);
+ #endif
  
        /* Check for keyboard input */
        /* If there is any, return immediately
***************
*** 2185,2188 ****
    defsubr (&Swaiting_for_user_input_p);
  }
  
! #endif subprocesses
--- 2259,2262 ----
    defsubr (&Swaiting_for_user_input_p);
  }
  
! #endif /* subprocesses */
===================================================================
RCS file: sysdep.c,v
retrieving revision 18.54
diff -c -r18.54 sysdep.c
*** /tmp/,RCSt1a13347	Thu Jan  4 14:18:33 1990
--- sysdep.c	Thu Dec 28 18:22:39 1989
***************
*** 100,105 ****
--- 100,109 ----
  #include <sys/ioctl.h>
  #endif 
  
+ #ifdef mips
+ #include <sys/ioctl.h>
+ #endif 
+ 
  /* Get rid of LLITOUT in 4.1, since it is said to stimulate kernel bugs.  */
  #ifdef BSD4_1
  #undef LLITOUT
***************
*** 120,127 ****
  #define TABS_OK(str) ((str.c_oflag & TABDLY) != TAB3)
  #endif /* HAVE_TERMIO */
  
! #ifdef XENIX
  #undef TIOCGETC  /* Avoid confusing some conditionals that test this.  */
  #endif
  
  #ifndef HAVE_TERMIO
--- 124,139 ----
  #define TABS_OK(str) ((str.c_oflag & TABDLY) != TAB3)
  #endif /* HAVE_TERMIO */
  
! #ifdef USG
  #undef TIOCGETC  /* Avoid confusing some conditionals that test this.  */
+ #ifdef TIOCGWINSZ
+ #include <sys/stream.h>
+ #include <sys/ptem.h>
+ #endif
+ #endif
+ 
+ #ifdef BROKEN_FIONREAD
+ #undef FIONREAD
  #endif
  
  #ifndef HAVE_TERMIO
***************
*** 140,145 ****
--- 152,162 ----
  #include <sys/utsname.h>
  #include <memory.h>
  #include <string.h>
+ #ifdef TIOCGWINSZ
+ #ifndef i386
+ #include <sys/sioctl.h>
+ #endif
+ #endif
  #ifdef HAVE_TIMEVAL
  #ifdef HPUX
  #include <time.h>
***************
*** 501,508 ****
--- 518,529 ----
      }
    return -1;
  #else
+ #ifdef SIGTSTP
  #ifdef BSD
    killpg (getpgrp (0), SIGTSTP);
+ #else
+   kill (-getpgrp (0), SIGTSTP);
+ #endif
  
  #else
  #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
***************
*** 760,766 ****
        sg.c_oflag &= ~TAB3;	/* Disable tab expansion */
  #ifdef CS8
        sg.c_cflag |= CS8;	/* allow 8th bit on input */
-       sg.c_cflag &= ~PARENB;	/* Don't check parity */
  #endif
        sg.c_cc[VINTR] = '\007';	/* ^G gives SIGINT */
        /* Set up C-g for both SIGQUIT and SIGINT.
--- 781,786 ----
***************
*** 834,839 ****
--- 854,860 ----
  	   If not going to use CBREAK mode, do this anyway
  	   so as to turn off local flow control for user coming over
  	   network on 4.2; in this case, only t_stopc and t_startc really matter.  */
+ #ifndef HAVE_TERMIO
  #ifdef TIOCGLTC
        ioctl (0, TIOCGLTC, &old_ltchars);
  #endif /* TIOCGLTC */
***************
*** 866,871 ****
--- 887,893 ----
  #ifdef TIOCGLTC
        ioctl (0, TIOCSLTC, &new_ltchars);
  #endif /* TIOCGLTC */
+ #endif /* not HAVE_TERMIO */
  
  #ifdef BSD4_1
        if (interrupt_input)
***************
*** 987,992 ****
--- 1009,1015 ----
    fsync (fileno (stdout));
  #endif
  #endif
+ #ifndef HAVE_TERMIO
  #ifdef TIOCGLTC
    ioctl (0, TIOCSLTC, &old_ltchars);
  #endif /* TIOCGLTC */
***************
*** 994,999 ****
--- 1017,1023 ----
    ioctl (0, TIOCSETC, &old_tchars);
    ioctl (0, TIOCLSET, &old_lmode);
  #endif /* TIOCGETC */
+ #endif /* not HAVE_TERMIO */
  #ifdef F_SETFL
  #ifdef F_SETOWN		/* F_SETFL does not imply existance of F_SETOWN */
    if (interrupt_input)
***************
*** 1393,1398 ****
--- 1417,1571 ----
  #endif /* not USG */
  }
  
+ #ifdef HAVE_POLL
+ 
+ #ifndef HAVE_SELECT
+ # define HAVE_SELECT
+ #endif
+ 
+ /*
+     This procedure emulates the 4.2BSD select(2) system call
+     using the System V STREAMS poll(2) system call.
+ 
+     First of all a bit of theory:
+ 
+     int select(int nfds,long *in,long *out,long *urg,struct timeval *tv)
+ 
+ 	The three arguments are pointers to 32 bit bitmaps representing
+ 	sets of file descriptors. Each set is initialized with a bitmap
+ 	of file descriptors to check.
+ 
+ 	Select(2) will keep on all bits
+ 	in each bitmap on which file descriptor respectively input is not
+ 	ready would block, or for which urgent conditions exist.
+ 
+ 	If no such bit is on after the given timeout, then select
+ 	returns.
+ 
+     int poll(struct pollfd *pollfd,unsigned count,unsigned ms)
+ 
+         each element of the first argument has three fields;
+ 	the first is a file descriptor, the second is a mask of
+ 	which events should be waited for for it, the third is a
+ 	mask of which did occur. Events to wait for may be input
+ 	is ready, write will not block, urgent info is waiting.
+ 
+ 	If none of the events waited for on any of the file descriptors
+ 	has occured within the number of milliseconds given by the
+ 	last argument, the call returns.
+ 
+ 	The second argument is the number of file descriptors to test;
+ 	it may not exceed NPOLLFILE.
+ 
+     As it is fairly obvious the two calls are broadly similar; the main
+     difference is that the mapping (fd x event) is parallel in select(2),
+     and serial in poll(2).
+ 
+     The only difficulty is that the maximum number of descriptors handled
+     by the two calls is potentially different, so if the number of descriptors
+     to test in any one call of select(2) is greater than NPOLLFILE, we
+     silently ignore the test of the remaining ones. This is highly
+     debatable, but it is highly unlikely to matter...
+ */
+ 
+ #include <sys/poll.h>
+ 
+ #ifndef HAVE_TIMEVAL
+ struct timeval
+ {
+     long		tv_sec;
+     long		tv_usec;
+ };
+ #endif
+ 
+ int			select(nselfile,inp,outp,urgp,tv)
+     int			    nselfile;
+     long		    *inp,*outp,*urgp;
+ #ifdef HAVE_TIMEVAL
+     struct timeval	    *tv;
+ #else
+      int		    *secs;
+ #endif
+ {
+     struct pollfd	    fd[NPOLLFILE];
+     register struct pollfd  *fp;
+     short unsigned	    fs;
+     register long	    fm;
+     register long	    in,out,urg;
+     register long	    all;
+     int			    ms;
+ 
+ #ifdef HAVE_TIMEVAL
+     ms = (tv) ? tv->tv_sec*100+tv->tv_usec/10 : -1;
+ #else
+     ms = (secs) ? secs*1000 : -1;
+ #endif
+ 
+     in = (inp) ? *inp : 0L;
+     out = (outp) ? *outp : 0L;
+     urg = (urgp) ? *urgp : 0L;
+ 
+     all = in|out|urg;
+ 
+     for
+     (
+          fm = 1, fs = 0, fp = fd;
+          all && fs < nselfile && fp < fd+NPOLLFILE;
+ 	 fm <<= 1, fs++
+     )
+     {
+ 	if (all & fm)
+ 	{
+ 	    register short unsigned events;
+ 
+ 	    all &=~ fm;
+ 	    events = 0;
+ 
+ 	    if (in & fm)		events |= POLLIN;
+ 	    if (out & fm)		events |= POLLOUT;
+ 	    if (urg & fm)		events |= POLLPRI;
+ 
+ 	    fp->events = events;
+ 	    fp->fd = fs;
+ 
+ 	    fp++;
+ 	}
+     }
+ 
+     if (poll(fd,(long) (fp-fd),ms) < 0)
+ 	return -1;
+ 
+     for (nselfile = 0, fp; fp != fd; --fp)
+     {
+ 	register short unsigned revents;
+ 
+ 	fm = 1 << fp[-1].fd;
+ 	revents = fp[-1].revents;
+ 
+ 	if (revents & POLLNVAL)
+ 	{
+ 	    errno = EBADF;
+ 	    return -1;
+         }
+ 
+ 	if (revents & (POLLIN|POLLOUT|POLLPRI))
+ 	{
+ 	    nselfile++;
+ 
+ 	    if (!(revents & POLLIN))	in &=~ fm;
+ 	    if (!(revents & POLLOUT))	out &=~ fm;
+ 	    if (!(revents & POLLPRI))	urg &=~ fm;
+         }
+     }
+ 
+     if (inp) *inp = in;
+     if (outp) *outp = out;
+     if (urgp) *urgp = urg;
+ 
+     return nselfile;
+ }
+ #endif /* HAVE_POLL */
+ 
  #ifndef HAVE_SELECT
  
  /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
***************
*** 1425,1433 ****
  
  /* Only rfds are checked and timeout must point somewhere */
  int
! select (nfds, rfds, wfds, efds, timeout)
       int nfds;
!      int *rfds, *wfds, *efds, *timeout;
  {
    int ravail = 0, orfds = 0, old_alarm;
    extern int kbd_count;
--- 1598,1611 ----
  
  /* Only rfds are checked and timeout must point somewhere */
  int
! select (nfds, rfds, wfds, efds, tv)
       int nfds;
!      int *rfds, *wfds, *efds;
! #ifdef HAVE_TIMEVAL
!      struct timeval *tv;
! #else
!      int *tv;
! #endif
  {
    int ravail = 0, orfds = 0, old_alarm;
    extern int kbd_count;
***************
*** 1439,1444 ****
--- 1617,1633 ----
  #endif
    int (*old_trap) ();
    char buf;
+   int *timeout;
+ #ifdef HAVE_TIMEVAL
+   int timerout;
+ 
+   timerout = (tv == 0) ? 100000
+     : (tv->tv_sec) ? tv->tv_sec
+       : (tv->tv_usec) ? 1 : 0;
+   timeout = &timerout;
+ #else
+   timeout = tv;
+ #endif
  
    if (rfds)
      {
***************
*** 1810,1819 ****
  
    d_name.dsc$w_length = strlen (name);
    d_name.dsc$a_pointer = name;
!   if (lib$sys_trnlog(&d_name, &eqlen, &equiv) == 1)
      {
!       buf[eqlen] = '\0';
!       return buf;
      }
    return (char *) getenv (name);
  }
--- 1999,2012 ----
  
    d_name.dsc$w_length = strlen (name);
    d_name.dsc$a_pointer = name;
!   if (lib$sys_trnlog (&d_name, &eqlen, &equiv) == 1)
      {
!       char *str = (char *) xmalloc (eqlen + 1);
!       bcopy (buf, str, eqlen);
!       str[eqlen] = '\0';
!       /* This is a storage leak, but a pain to fix.  With luck,
! 	 no one will ever notice.  */
!       return str;
      }
    return (char *) getenv (name);
  }
===================================================================
RCS file: unexec.c,v
retrieving revision 18.54
diff -c -r18.54 unexec.c
*** /tmp/,RCSt1a13347	Thu Jan  4 14:18:41 1990
--- unexec.c	Thu Dec 28 18:22:43 1989
***************
*** 400,406 ****
      }
  
    if (make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) < 0
!       || copy_text_and_data (new) < 0
        || copy_sym (new, a_out, a_name, new_name) < 0
  #ifdef COFF
        || adjust_lnnoptrs (new, a_out, new_name) < 0
--- 400,406 ----
      }
  
    if (make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) < 0
!       || copy_sections (new, a_out) < 0
        || copy_sym (new, a_out, a_name, new_name) < 0
  #ifdef COFF
        || adjust_lnnoptrs (new, a_out, new_name) < 0
***************
*** 440,446 ****
    auto struct scnhdr scntemp;		/* Temporary section header */
    register int scns;
  #endif /* COFF */
!   unsigned int bss_end;
  
    pagemask = getpagesize () - 1;
  
--- 440,446 ----
    auto struct scnhdr scntemp;		/* Temporary section header */
    register int scns;
  #endif /* COFF */
!   extern unsigned int bss_end;
  
    pagemask = getpagesize () - 1;
  
***************
*** 533,538 ****
--- 533,541 ----
    /* Now we alter the contents of all the f_*hdr variables
       to correspond to what we want to dump.  */
  
+   bias = (bss_start - f_ohdr.data_start) + (bss_end - bss_start) -
+     f_dhdr.s_size;
+ 
    f_hdr.f_flags |= (F_RELFLG | F_EXEC);
  #ifdef EXEC_MAGIC
    f_ohdr.magic = EXEC_MAGIC;
***************
*** 576,582 ****
    f_bhdr.s_vaddr = f_ohdr.data_start + f_ohdr.dsize;
    f_bhdr.s_size = f_ohdr.bsize;
    f_bhdr.s_scnptr = 0L;
-   bias = f_dhdr.s_scnptr + f_dhdr.s_size - block_copy_start;
  
    if (f_hdr.f_symptr > 0L)
      {
--- 579,584 ----
***************
*** 602,621 ****
        PERROR (new_name);
      }
  
!   if (write (new, &f_thdr, sizeof (f_thdr)) != sizeof (f_thdr))
!     {
!       PERROR (new_name);
!     }
  
!   if (write (new, &f_dhdr, sizeof (f_dhdr)) != sizeof (f_dhdr))
!     {
!       PERROR (new_name);
!     }
  
-   if (write (new, &f_bhdr, sizeof (f_bhdr)) != sizeof (f_bhdr))
-     {
-       PERROR (new_name);
-     }
    return (0);
  
  #else /* if not COFF */
--- 604,632 ----
        PERROR (new_name);
      }
  
!   lseek(a_out, sizeof f_hdr + sizeof f_ohdr, 0);
  
!   for (scns = f_hdr.f_nscns; scns > 0; scns--) {
!      if (read (a_out, &scntemp, sizeof (scntemp)) != sizeof (scntemp))
!        PERROR (a_name);
! 
!      if (!strcmp(scntemp.s_name, f_thdr.s_name)) {
! 	if (write (new, &f_thdr, sizeof (f_thdr)) != sizeof (f_thdr))
! 	  PERROR (new_name);
!      } else if (!strcmp(scntemp.s_name, f_dhdr.s_name)) {
! 	if (write (new, &f_dhdr, sizeof (f_dhdr)) != sizeof (f_dhdr))
! 	   PERROR (new_name);
!      } else if (!strcmp(scntemp.s_name, f_bhdr.s_name)) {
! 	if (write (new, &f_bhdr, sizeof (f_bhdr)) != sizeof (f_bhdr))
! 	   PERROR (new_name);
!      } else {
! 	if (scntemp.s_scnptr)
! 	  scntemp.s_scnptr += bias;
! 	if (write (new, &scntemp, sizeof (scntemp)) != sizeof (scntemp))
! 	  PERROR (new_name);
!      }
!   }
  
    return (0);
  
  #else /* if not COFF */
***************
*** 680,706 ****
  }
  
  /* ****************************************************************
!  * copy_text_and_data
   *
!  * Copy the text and data segments from memory to the new a.out
   */
  static int
! copy_text_and_data (new)
!      int new;
  {
    register char *end;
    register char *ptr;
  
  #ifdef COFF
!   lseek (new, (long) text_scnptr, 0);
!   ptr = (char *) f_ohdr.text_start;
!   end = ptr + f_ohdr.tsize;
!   write_segment (new, ptr, end);
  
!   lseek (new, (long) data_scnptr, 0);
!   ptr = (char *) f_ohdr.data_start;
!   end = ptr + f_ohdr.dsize;
!   write_segment (new, ptr, end);
  
  #else /* if not COFF */
  
--- 691,743 ----
  }
  
  /* ****************************************************************
!  * copy_sections
   *
!  * Copy all sections to the new a.out
   */
  static int
! copy_sections (new, a_out)
!      int new, a_out;
  {
    register char *end;
    register char *ptr;
+   register int scns;
+   auto struct scnhdr scntemp;		/* Temporary section header */
  
  #ifdef COFF
! 
!   lseek(a_out, sizeof(struct filehdr) + sizeof(struct aouthdr), 0);
  
!   for (scns = f_hdr.f_nscns; scns > 0; scns--) {
!      if (read (a_out, &scntemp, sizeof (scntemp)) != sizeof (scntemp))
!        PERROR ("temacs");
! 
!      if (!strcmp(scntemp.s_name, ".text")) {
! 	lseek (new, (long) text_scnptr, 0);
! 	ptr = (char *) f_ohdr.text_start;
! 	end = ptr + f_ohdr.tsize;
! 	write_segment (new, ptr, end);
!      } else if (!strcmp(scntemp.s_name, ".data")) {
! 	lseek (new, (long) data_scnptr, 0);
! 	ptr = (char *) f_ohdr.data_start;
! 	end = ptr + f_ohdr.dsize;
! 	write_segment (new, ptr, end);
!      } else if (!scntemp.s_scnptr)
!        ; /* do nothing - no data for this section */
!      else {
! 	char page[BUFSIZ];
! 	int size, n;
! 	int old_a_out_ptr = lseek(a_out, 0, 1);
! 
! 	lseek(a_out, scntemp.s_scnptr, 0);
! 	for (size = scntemp.s_size; size > 0; size -= sizeof page) {
! 	   n = size > sizeof page ? sizeof page : size;
! 	   if (read(a_out, page, n) != n || write(new, page, n) != n)
! 	     PERROR ("xemacs");
! 	}
! 	lseek(a_out, old_a_out_ptr, 0);
!      }
!   }
  
  #else /* if not COFF */
  

-- 
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk at nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg at cs.aber.ac.uk



More information about the Comp.unix.i386 mailing list