[net.emacs] GNU Emacs hanging...

gaynor@topaz.RUTGERS.EDU (Silver) (10/13/86)

[ Be the first on your block! ]

Sorry to bother you all, but I have an annoying problem.  I run GNU
Emacs 17.57.18 from a sun2-window remotely logged in to a pyramid 98x
running 3.2 BSD Unix.  I am quite often hung while trying to bring it
back to the foreground after suspending it.

Any suggestions?  Please use e-mail.  Flames?  You know which device
they belong to...  :-).

Frequently insane,
Silver.

uucp:  ...!topaz!gaynor  ...!topaz!remus!gaynor
arpa:  gaynor@topaz      silver@gold

"Savoir Faire is everywhere!" - Savoir Faire

gaynor@topaz.RUTGERS.EDU (Silver) (10/13/86)

Um, in my most previous post, I meant '4.2 BSD Unix'...

Apologies to all offended,
Silver.

lamy@utai.UUCP (Jean-Francois Lamy) (10/14/86)

>Sorry to bother you all, but I have an annoying problem.  I run GNU
>Emacs 17.57.18 from a sun2-window remotely logged in to a pyramid 98x
>running [4].2 BSD Unix.  I am quite often hung while trying to bring it
>back to the foreground after suspending it.

Exactly the same problem occurs with GNU 17.64 when remote logged on a
4.2BSD Vax, from Sun 2/ Sun 3 Workstations running 3.0.  To reproduce
the bug, just edit with GNU long enough, going often to the background.
There does not seem to be any correlation with what state GNU was in
when you suspend it.  GNU emacs is the only program I've seen that
provokes that behaviour.

Jean-Francois Lamy
AI Group, Dept of Computer Science     CSNet: lamy@ai.toronto.edu
University of Toronto		       EAN:   lamy@ai.toronto.cdn
Toronto, ON, Canada M5S 1A4	       UUCP:  lamy@utai.uucp

mwm@eris.berkeley.edu (Mike Meyer) (10/16/86)

In article <2536@utai.UUCP> lamy@utai.UUCP (Jean-Francois Lamy) writes:
>
>>Sorry to bother you all, but I have an annoying problem.  I run GNU
>>Emacs 17.57.18 from a sun2-window remotely logged in to a pyramid 98x
>>running [4].2 BSD Unix.  I am quite often hung while trying to bring it
>>back to the foreground after suspending it.
>
>Exactly the same problem occurs with GNU 17.64 when remote logged on a
>4.2BSD Vax, from Sun 2/ Sun 3 Workstations running 3.0.  To reproduce
>the bug, just edit with GNU long enough, going often to the background.
>There does not seem to be any correlation with what state GNU was in
>when you suspend it.  GNU emacs is the only program I've seen that
>provokes that behaviour.

Ditto, except for more data points:

rlogged in from either a Sun-3 any of a 4.[23] 750, a 4.3beta 8600, a
4.3 8600, or an Ultrix 2.0beta 8800. Also from a uvax ][ to either a
4.2 750 or a 4.3beta 8600.

GNU version is 17.63, and there's at least one version of microEmacs
that has the same problem.

The problem seems occurs more often with longer windows, and rlogged
in to faster hosts. I suspect a kernel bug, myself, but would be
interested to see any solution. 

	<mike

chris@umcp-cs.UUCP (Chris Torek) (10/17/86)

In article <1456@jade.BERKELEY.EDU> mwm@eris.berkeley.edu (Mike Meyer) writes:
>Ditto, except for more data points:
>
>rlogged in from either a Sun-3 any of a 4.[23] 750, a 4.3beta 8600, a
>4.3 8600, or an Ultrix 2.0beta 8800. Also from a uvax ][ to either a
>4.2 750 or a 4.3beta 8600.

I cannot quite parse that, but I gather the problem shows when running
rlogin within a window, whenever the remote host is `fast'.

>I suspect a kernel bug, myself, but would be interested to see any
>solution.

Rlogin bugs are more likely.  The 4.2 version was thoroughly broken.
The 4.3 version was significantly reworked but still not quite
right.  The Sun version was hopeless; I replaced it with a fixed 4.3
version.  I know naught of the Ultrix rlogin.

The Solution (as far as I know):

Copy your 4.3 rlogin.c and your 4.3 /usr/src/lib/libc/net/rcmd.c
files to your Sun or uVax-II.  Apply the changes shown below to
rlogin.c.  Compile rlogin.c and rcmd.c to .o's, then link together
and test.  This requires super-user privileges (alas!).  You may
discover that you need to reverse the sense of the `pid' arguments
to the fcntl(F_SETOWN) calls; I forget whether they work as is on
the Suns.  (4.2 had pid and pgrp logically reversed; `fixed in 4.3'
means `incompatible with 4.2'.  So it goes.)

You may want to pull out the `isswitch' code.  We used to use a
local hack to allow remote logins without local accounts, by adding
/etc/passwd entries of the form

	imladris::20:199:& Switch:/tmp:/usr/ucb/rswtch

Logging in as `imladris' (ah, the name evokes such memories) would
send you over to my Sun-3/50, where you would then be asked for a
login name and password.  We now have a different local hack; I just
log in as `chris@imladris' if I wish.

Anyway, here are the fixes for a 4.3 rlogin.c.  Do not be concerned
by the size: I fixed all the lint fluff, and reworked some of the
Sun-specific window code for readability.

*** /x/chris/4.3tape/src/ucb/rlogin.c	Sun Mar 30 19:39:06 1986
--- rlogin.c	Thu Aug  7 02:24:40 1986
***************
*** 22,25 ****
--- 22,27 ----
  #include <sys/file.h>
  #include <sys/socket.h>
+ #include <sys/time.h>
+ #include <sys/resource.h>
  #include <sys/wait.h>
  
***************
*** 38,42 ****
  # endif TIOCPKT_WINDOW
  
! char	*index(), *rindex(), *malloc(), *getenv();
  struct	passwd *getpwuid();
  char	*name;
--- 40,49 ----
  # endif TIOCPKT_WINDOW
  
! /* concession to sun */
! # ifndef SIGUSR1
! # define SIGUSR1 30
! # endif SIGUSR1
! 
! char	*index(), *rindex(), *malloc(), *getenv(), *strcat(), *strcpy();
  struct	passwd *getpwuid();
  char	*name;
***************
*** 43,46 ****
--- 50,54 ----
  int	rem;
  char	cmdchar = '~';
+ int	isswitch;
  int	eight;
  int	litout;
***************
*** 56,60 ****
  #endif
  #ifdef sun
- struct	ttysize winsize;
  struct winsize {
  	unsigned short ws_row, ws_col;
--- 64,67 ----
***************
*** 61,69 ****
  	unsigned short ws_xpixel, ws_ypixel;
  };
- #else sun
- struct	winsize winsize;
  #endif sun
  int	sigwinch(), oob();
  
  main(argc, argv)
  	int argc;
--- 68,101 ----
  	unsigned short ws_xpixel, ws_ypixel;
  };
  #endif sun
+ struct	winsize winsize;
  int	sigwinch(), oob();
  
+ /*
+  * The following routine provides compatibility (such as it is)
+  * between 4.2BSD Suns and others.  Suns have only a `ttysize',
+  * so we convert it to a winsize.
+  */
+ #ifdef sun
+ int
+ get_window_size(fd, wp)
+ 	int fd;
+ 	struct winsize *wp;
+ {
+ 	struct ttysize ts;
+ 	int error;
+ 
+ 	if ((error = ioctl(0, TIOCGSIZE, &ts)) != 0)
+ 		return (error);
+ 	wp->ws_row = ts.ts_lines;
+ 	wp->ws_col = ts.ts_cols;
+ 	wp->ws_xpixel = 0;
+ 	wp->ws_ypixel = 0;
+ 	return (0);
+ }
+ #else sun
+ #define get_window_size(fd, wp)	ioctl(fd, TIOCGWINSZ, wp)
+ #endif sun
+ 
  main(argc, argv)
  	int argc;
***************
*** 85,88 ****
--- 117,143 ----
  	if (!strcmp(host, "rlogin"))
  		host = *argv++, --argc;
+ 	else if (!strcmp(host, "rswtch")) {
+ 		printf("You really don't want to run this.\n");
+ 		exit(1);
+ 	} else if (argc == 0 && host[0] == '-') {
+ 		static char namebuf[128];
+ 		char *getlogin();
+ 
+ 		/*
+ 		 * This is a hack.  If you log in with "rswtch" as
+ 		 * your shell, we assume you really want to remotely
+ 		 * log in to some other host.  This disables commands
+ 		 * and makes us prompt for a login name.
+ 		 */
+ 		if ((host = getlogin()) == NULL) {
+ 			printf("Oops - getlogin\n");
+ 			exit(1);
+ 		}
+ 		isswitch++;
+ 		(void) printf("Remote login name: ");
+ 		(void) fflush(stdout);
+ 		(void) gets(namebuf);
+ 		name = namebuf;
+ 	}
  another:
  	if (argc > 0 && !strcmp(*argv, "-d")) {
***************
*** 117,124 ****
  	if (argc > 0)
  		goto usage;
! 	pwd = getpwuid(getuid());
! 	if (pwd == 0) {
! 		fprintf(stderr, "Who are you?\n");
! 		exit(1);
  	}
  	sp = getservbyname("login", "tcp");
--- 172,181 ----
  	if (argc > 0)
  		goto usage;
! 	if (!isswitch) {
! 		pwd = getpwuid(getuid());
! 		if (pwd == 0) {
! 			fprintf(stderr, "Who are you?\n");
! 			exit(1);
! 		}
  	}
  	sp = getservbyname("login", "tcp");
***************
*** 129,146 ****
  	cp = getenv("TERM");
  	if (cp)
! 		strcpy(term, cp);
  	if (ioctl(0, TIOCGETP, &ttyb) == 0) {
! 		strcat(term, "/");
! 		strcat(term, speeds[ttyb.sg_ospeed]);
  	}
! #ifdef sun
! 	(void) ioctl(0, TIOCGSIZE, &winsize);
! #else sun
! 	(void) ioctl(0, TIOCGWINSZ, &winsize);
! #endif sun
! 	signal(SIGPIPE, lostpeer);
! 	signal(SIGURG, oob);
! 	oldmask = sigblock(sigmask(SIGURG));
!         rem = rcmd(&host, sp->s_port, pwd->pw_name,
  	    name ? name : pwd->pw_name, term, 0);
          if (rem < 0)
--- 186,199 ----
  	cp = getenv("TERM");
  	if (cp)
! 		(void) strcpy(term, cp);
  	if (ioctl(0, TIOCGETP, &ttyb) == 0) {
! 		(void) strcat(term, "/");
! 		(void) strcat(term, speeds[ttyb.sg_ospeed]);
  	}
! 	(void) get_window_size(0, &winsize);
! 	(void) signal(SIGPIPE, lostpeer);
! 	/* will use SIGUSR1 for window size hack, so hold it off */
! 	oldmask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1));
!         rem = rcmd(&host, sp->s_port, isswitch ? "anybody" : pwd->pw_name,
  	    name ? name : pwd->pw_name, term, 0);
          if (rem < 0)
***************
*** 166,170 ****
  int	child;
  int	catchild();
! int	writeroob();
  
  int	defflags, tabflag;
--- 219,223 ----
  int	child;
  int	catchild();
! int	copytochild(), writeroob();
  
  int	defflags, tabflag;
***************
*** 181,185 ****
  	struct sgttyb sb;
  
! 	ioctl(0, TIOCGETP, (char *)&sb);
  	defflags = sb.sg_flags;
  	tabflag = defflags & TBDELAY;
--- 234,238 ----
  	struct sgttyb sb;
  
! 	(void) ioctl(0, TIOCGETP, (char *)&sb);
  	defflags = sb.sg_flags;
  	tabflag = defflags & TBDELAY;
***************
*** 187,198 ****
  	deferase = sb.sg_erase;
  	defkill = sb.sg_kill;
! 	ioctl(0, TIOCLGET, (char *)&deflflags);
! 	ioctl(0, TIOCGETC, (char *)&deftc);
  	notc.t_startc = deftc.t_startc;
  	notc.t_stopc = deftc.t_stopc;
! 	ioctl(0, TIOCGLTC, (char *)&defltc);
! 	signal(SIGINT, SIG_IGN);
! 	signal(SIGHUP, exit);
! 	signal(SIGQUIT, exit);
  	child = fork();
  	if (child == -1) {
--- 240,251 ----
  	deferase = sb.sg_erase;
  	defkill = sb.sg_kill;
! 	(void) ioctl(0, TIOCLGET, (char *)&deflflags);
! 	(void) ioctl(0, TIOCGETC, (char *)&deftc);
  	notc.t_startc = deftc.t_startc;
  	notc.t_stopc = deftc.t_stopc;
! 	(void) ioctl(0, TIOCGLTC, (char *)&defltc);
! 	(void) signal(SIGINT, SIG_IGN);
! 	setsignal(SIGHUP, exit);
! 	setsignal(SIGQUIT, exit);
  	child = fork();
  	if (child == -1) {
***************
*** 202,207 ****
  	if (child == 0) {
  		mode(1);
! 		sigsetmask(oldmask);
! 		if (reader() == 0) {
  			prf("Connection closed.");
  			exit(0);
--- 255,259 ----
  	if (child == 0) {
  		mode(1);
! 		if (reader(oldmask) == 0) {
  			prf("Connection closed.");
  			exit(0);
***************
*** 211,217 ****
  		exit(3);
  	}
! 	signal(SIGURG, writeroob);
! 	sigsetmask(oldmask);
! 	signal(SIGCHLD, catchild);
  	writer();
  	prf("Closed connection.");
--- 263,277 ----
  		exit(3);
  	}
! 
! 	/*
! 	 * We may still own the socket, and may have a pending SIGURG
! 	 * (or might receive one soon) that we really want to send to
! 	 * the reader.  Set a trap that simply copies such signals to
! 	 * the child.
! 	 */
! 	(void) signal(SIGURG, copytochild);
! 	(void) signal(SIGUSR1, writeroob);
! 	(void) sigsetmask(oldmask);
! 	(void) signal(SIGCHLD, catchild);
  	writer();
  	prf("Closed connection.");
***************
*** 219,229 ****
  }
  
  done(status)
  	int status;
  {
  
  	mode(0);
! 	if (child > 0 && kill(child, SIGKILL) >= 0)
! 		wait((int *)0);
  	exit(status);
  }
--- 279,308 ----
  }
  
+ /*
+  * Trap a signal, unless it is being ignored.
+  */
+ setsignal(sig, act)
+ 	int sig, (*act)();
+ {
+ 	int omask = sigblock(sigmask(sig));
+ 
+ 	if (signal(sig, act) == SIG_IGN)
+ 		(void) signal(sig, SIG_IGN);
+ 	(void) sigsetmask(omask);
+ }
+ 
  done(status)
  	int status;
  {
+ 	int w;
  
  	mode(0);
! 	if (child > 0) {
! 		/* make sure catchild does not snap it up */
! 		(void) signal(SIGCHLD, SIG_DFL);
! 		if (kill(child, SIGKILL) >= 0)
! 			while ((w = wait((union wait *)0)) > 0 && w != child)
! 				/*void*/;
! 	}
  	exit(status);
  }
***************
*** 230,233 ****
--- 309,321 ----
  
  /*
+  * Copy SIGURGs to the child process.
+  */
+ copytochild()
+ {
+ 
+ 	(void) kill(child, SIGURG);
+ }
+ 
+ /*
   * This is called when the reader process gets the out-of-band (urgent)
   * request to turn on the window-changing protocol.
***************
*** 238,242 ****
  	if (dosigwinch == 0) {
  		sendwindow();
! 		signal(SIGWINCH, sigwinch);
  	}
  	dosigwinch = 1;
--- 326,330 ----
  	if (dosigwinch == 0) {
  		sendwindow();
! 		(void) signal(SIGWINCH, sigwinch);
  	}
  	dosigwinch = 1;
***************
*** 249,253 ****
  
  again:
! 	pid = wait3(&status, WNOHANG|WUNTRACED, 0);
  	if (pid == 0)
  		return;
--- 337,341 ----
  
  again:
! 	pid = wait3(&status, WNOHANG|WUNTRACED, (struct rusage *)0);
  	if (pid == 0)
  		return;
***************
*** 256,260 ****
  	 */
  	if (pid < 0 || pid == child && !WIFSTOPPED(status))
! 		done(status.w_termsig | status.w_retcode);
  	goto again;
  }
--- 344,348 ----
  	 */
  	if (pid < 0 || pid == child && !WIFSTOPPED(status))
! 		done((int)(status.w_termsig | status.w_retcode));
  	goto again;
  }
***************
*** 290,294 ****
  		if (bol) {
  			bol = 0;
! 			if (c == cmdchar) {
  				bol = 0;
  				local = 1;
--- 378,382 ----
  		if (bol) {
  			bol = 0;
! 			if (!isswitch && c == cmdchar) {
  				bol = 0;
  				local = 1;
***************
*** 308,312 ****
  			}
  			if (c != cmdchar)
! 				write(rem, &cmdchar, 1);
  		}
  		if (write(rem, &c, 1) == 0) {
--- 396,400 ----
  			}
  			if (c != cmdchar)
! 				(void) write(rem, &cmdchar, 1);
  		}
  		if (write(rem, &c, 1) == 0) {
***************
*** 338,342 ****
  	*p++ = '\r';
  	*p++ = '\n';
! 	write(1, buf, p - buf);
  }
  
--- 426,430 ----
  	*p++ = '\r';
  	*p++ = '\n';
! 	(void) write(1, buf, p - buf);
  }
  
***************
*** 345,351 ****
  {
  	mode(0);
! 	signal(SIGCHLD, SIG_IGN);
! 	kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP);
! 	signal(SIGCHLD, catchild);
  	mode(1);
  	sigwinch();			/* check for size changes */
--- 433,439 ----
  {
  	mode(0);
! 	(void) signal(SIGCHLD, SIG_IGN);
! 	(void) kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP);
! 	(void) signal(SIGCHLD, catchild);
  	mode(1);
  	sigwinch();			/* check for size changes */
***************
*** 352,373 ****
  }
  
- #ifdef sun
  sigwinch()
  {
- 	struct ttysize ws;
- 
- 	if (dosigwinch && ioctl(0, TIOCGSIZE, &ws) == 0 &&
- 	    bcmp(&ws, &winsize, sizeof (ws))) {
- 		winsize = ws;
- 		sendwindow();
- 	}
- }
- 
- #else sun
- sigwinch()
- {
  	struct winsize ws;
  
! 	if (dosigwinch && ioctl(0, TIOCGWINSZ, &ws) == 0 &&
  	    bcmp(&ws, &winsize, sizeof (ws))) {
  		winsize = ws;
--- 440,448 ----
  }
  
  sigwinch()
  {
  	struct winsize ws;
  
! 	if (dosigwinch && get_window_size(0, &ws) == 0 &&
  	    bcmp(&ws, &winsize, sizeof (ws))) {
  		winsize = ws;
***************
*** 375,379 ****
  	}
  }
- #endif
  
  /*
--- 450,453 ----
***************
*** 389,398 ****
  	obuf[2] = 's';
  	obuf[3] = 's';
- #ifdef sun
- 	wp->ws_row = htons(winsize.ts_lines);
- 	wp->ws_col = htons(winsize.ts_cols);
- 	wp->ws_xpixel = 0;
- 	wp->ws_ypixel = 0;
- #else sun
  	wp->ws_row = htons(winsize.ws_row);
  	wp->ws_col = htons(winsize.ws_col);
--- 463,466 ----
***************
*** 399,403 ****
  	wp->ws_xpixel = htons(winsize.ws_xpixel);
  	wp->ws_ypixel = htons(winsize.ws_ypixel);
- #endif sun
  	(void) write(rem, obuf, sizeof(obuf));
  }
--- 467,470 ----
***************
*** 409,413 ****
  #define	WRITING	2
  
! char	rcvbuf[8 * 1024];
  int	rcvcnt;
  int	rcvstate;
--- 476,480 ----
  #define	WRITING	2
  
! char	rcvbuf[32 * 1024];
  int	rcvcnt;
  int	rcvstate;
***************
*** 452,477 ****
  		 * Let server know about window size changes
  		 */
! 		kill(ppid, SIGURG);
  	}
  	if (!eight && (mark & TIOCPKT_NOSTOP)) {
! 		ioctl(0, TIOCGETP, (char *)&sb);
  		sb.sg_flags &= ~CBREAK;
  		sb.sg_flags |= RAW;
! 		ioctl(0, TIOCSETN, (char *)&sb);
  		notc.t_stopc = -1;
  		notc.t_startc = -1;
! 		ioctl(0, TIOCSETC, (char *)&notc);
  	}
  	if (!eight && (mark & TIOCPKT_DOSTOP)) {
! 		ioctl(0, TIOCGETP, (char *)&sb);
  		sb.sg_flags &= ~RAW;
  		sb.sg_flags |= CBREAK;
! 		ioctl(0, TIOCSETN, (char *)&sb);
  		notc.t_stopc = deftc.t_stopc;
  		notc.t_startc = deftc.t_startc;
! 		ioctl(0, TIOCSETC, (char *)&notc);
  	}
  	if (mark & TIOCPKT_FLUSHWRITE) {
! 		ioctl(1, TIOCFLUSH, (char *)&out);
  		for (;;) {
  			if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
--- 519,544 ----
  		 * Let server know about window size changes
  		 */
! 		(void) kill(ppid, SIGUSR1);
  	}
  	if (!eight && (mark & TIOCPKT_NOSTOP)) {
! 		(void) ioctl(0, TIOCGETP, (char *)&sb);
  		sb.sg_flags &= ~CBREAK;
  		sb.sg_flags |= RAW;
! 		(void) ioctl(0, TIOCSETN, (char *)&sb);
  		notc.t_stopc = -1;
  		notc.t_startc = -1;
! 		(void) ioctl(0, TIOCSETC, (char *)&notc);
  	}
  	if (!eight && (mark & TIOCPKT_DOSTOP)) {
! 		(void) ioctl(0, TIOCGETP, (char *)&sb);
  		sb.sg_flags &= ~RAW;
  		sb.sg_flags |= CBREAK;
! 		(void) ioctl(0, TIOCSETN, (char *)&sb);
  		notc.t_stopc = deftc.t_stopc;
  		notc.t_startc = deftc.t_startc;
! 		(void) ioctl(0, TIOCSETC, (char *)&notc);
  	}
  	if (mark & TIOCPKT_FLUSHWRITE) {
! 		(void) ioctl(1, TIOCFLUSH, (char *)&out);
  		for (;;) {
  			if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
***************
*** 495,499 ****
--- 562,571 ----
  		longjmp(rcvtop, 1);
  	}
+ 
  	/*
+ 	 * oob does not do FLUSHREAD (alas!)
+ 	 */
+ 
+ 	/*
  	 * If we filled the receive buffer while a read was pending,
  	 * longjmp to the top to restart appropriately.  Don't abort
***************
*** 507,511 ****
   * reader: read from remote: line -> 1
   */
! reader()
  {
  #if !defined(BSD) || BSD < 43
--- 579,584 ----
   * reader: read from remote: line -> 1
   */
! reader(oldmask)
! 	int oldmask;
  {
  #if !defined(BSD) || BSD < 43
***************
*** 517,524 ****
  	char *bufp = rcvbuf;
  
! 	signal(SIGTTOU, SIG_IGN);
! 	fcntl(rem, F_SETOWN, pid);
  	ppid = getppid();
  	(void) setjmp(rcvtop);
  	for (;;) {
  		while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) {
--- 590,599 ----
  	char *bufp = rcvbuf;
  
! 	(void) signal(SIGTTOU, SIG_IGN);
! 	(void) signal(SIGURG, oob);
  	ppid = getppid();
+ 	(void) fcntl(rem, F_SETOWN, pid);
  	(void) setjmp(rcvtop);
+ 	(void) sigsetmask(oldmask);
  	for (;;) {
  		while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) {
***************
*** 554,559 ****
  	int	lflags;
  
! 	ioctl(0, TIOCGETP, (char *)&sb);
! 	ioctl(0, TIOCLGET, (char *)&lflags);
  	switch (f) {
  
--- 629,634 ----
  	int	lflags;
  
! 	(void) ioctl(0, TIOCGETP, (char *)&sb);
! 	(void) ioctl(0, TIOCLGET, (char *)&lflags);
  	switch (f) {
  
***************
*** 584,591 ****
  		return;
  	}
! 	ioctl(0, TIOCSLTC, (char *)ltc);
! 	ioctl(0, TIOCSETC, (char *)tc);
! 	ioctl(0, TIOCSETN, (char *)&sb);
! 	ioctl(0, TIOCLSET, (char *)&lflags);
  }
  
--- 659,666 ----
  		return;
  	}
! 	(void) ioctl(0, TIOCSLTC, (char *)ltc);
! 	(void) ioctl(0, TIOCSETC, (char *)tc);
! 	(void) ioctl(0, TIOCSETN, (char *)&sb);
! 	(void) ioctl(0, TIOCLSET, (char *)&lflags);
  }
  
***************
*** 594,597 ****
--- 669,673 ----
  	char *f;
  {
+ 
  	fprintf(stderr, f, a1, a2, a3, a4, a5);
  	fprintf(stderr, CRLF);
***************
*** 600,604 ****
  lostpeer()
  {
! 	signal(SIGPIPE, SIG_IGN);
  	prf("\007Connection closed.");
  	done(1);
--- 676,681 ----
  lostpeer()
  {
! 
! 	(void) signal(SIGPIPE, SIG_IGN);
  	prf("\007Connection closed.");
  	done(1);
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

whm@megaron.UUCP (10/18/86)

That's a bug in Sun's 3.0.  I first ran into the problem here with Unipress
Emacs and when I contacted Sun, they said that they had reports of this
happening with GNU emacs as well.  As I recall, they said it was fixed in
3.2 and they also supplied new versions of rlogin.o and tcp_output.o at
our request.  I think it also happened with "more".

I found that in many cases, the editor wouldn't really be hung, it would
just lose output.  For example, sometimes when I paused Unipress Emacs and
then brought it forward, it would seemingly hang, but if I typed the
key sequence to pause it, it would usually pause again and the shell would
be ok.  I could then bring it forward again and things would be ok.  Not
as good as a fix, but it usually worked.

					Bill Mitchell
					whm@arizona.edu
					{allegra,ihnp4,noao}!arizona!whm

escott%deis.uci.edu@ICS.UCI.EDU (Scott Menter) (10/18/86)

Mike Meyer <jade!eris!mwm@ucbvax.berkeley.edu> writes :
> In article <2536@utai.UUCP> lamy@utai.UUCP (Jean-Francois Lamy) writes:
>>
>>>Sorry to bother you all, but I have an annoying problem.  I run GNU
>>>Emacs 17.57.18 from a sun2-window remotely logged in to a pyramid 98x
>>>running [4].2 BSD Unix.  I am quite often hung while trying to bring it
>>>back to the foreground after suspending it.
> [...]
> The problem seems occurs more often with longer windows, and rlogged
> in to faster hosts. I suspect a kernel bug, myself, but would be
> interested to see any solution. 
> 

Me too.  Add Sequent's DYNIX 2.1 to the list of offenders.  I'm
running 17.61.  I've been hoping that maybe v18 fixes the problem
accidentally, but have yet to get the whole thing successfully with
ftp.  I've also noted that the problem is more frequent with longer
windows.

 Scott Menter
		Internet	escott@ics.uci.edu
		UUCP		...!ucbvax!ucivax!escott
		BITNET		escott@ucicp6

rbbb@RICE.EDU (David Chase) (10/19/86)

If you cannot wait for the fixes from Sun, you can avoid this problem by
adding two sleeps to your code.  The delay (1 second) is annoying, but it
absolutely avoids the problem (I know; it has not happened to me even once
since I did this, and that was at the beginning of the summer).

The places to sleep:

1) when setting the terminal back to its original (non-emacs) state,
insert a sleep AFTER you have sent the terminal-altering escape sequences,
BEFORE you perform whatever stty's are necessary to set the terminal in
its non-emacs state.

2) when setting the terminal into its emacs state, insert a sleep AFTER
you perform any stty's, BEFORE you send any sequences to the terminal.

Thus, you get something like:

enter_emacs() {
   stty(...)
   sleep(1)
   terminal_init()
   }

leave_emacs() {
   terminal_restore()
   sleep(1)
   stty(...)
   }

The one second sleep is a bit heavy-handed, but it was easy, does the job,
and isn't too offensive to users (especially after emacs has hung them up
once or twice).

This (hanging) happens a LOT if you are on a Sun 3 running Gosling emacs.

David

guy@sun.UUCP (10/21/86)

> That's a bug in Sun's 3.0.  I first ran into the problem here with Unipress
> Emacs and when I contacted Sun, they said that they had reports of this
> happening with GNU emacs as well.  As I recall, they said it was fixed in
> 3.2 and they also supplied new versions of rlogin.o and tcp_output.o at
> our request....

the vast bulk of changes to which were just fixes from 4.3BSD.  Yes, kids,
it's "fixed in 4.3" time!  (In any of the cases cited, was the "from"
machine running a 4.3 "rlogin"?)
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com (or guy@sun.arpa)