[comp.windows.x] X11 & SHELL PROBLEM

obrooks@NSWC-WO.ARPA (04/05/88)

	Upon termination of the server we return to the shell prompt
if we use the C shell. But if we use the Bourne or Korn shell we get
blown off the system and have to login again. I suspect that the 
Korn or Bourne shells are not catching a signal; I tried various 
combinations but could not get it to work. Our users use all three
shells for program development and would like to continue in a X
environment. 

	Does anyone have the same problem? Does anyone have a solution?
	We are running X11R2 on SUN 160s & 140s.


---------------------------------------------------------------------------
IN REAL LIFE:			ADDRESS:

Oscar Brooks			obrooks@nswc-wo.arpa
Naval Surface Warfare Center
10901 New Hampshire Ave
Silver Spring, MD. 20903
---------------------------------------------------------------------------

ekrell@hector.UUCP (Eduardo Krell) (04/09/88)

In article <8804051303.AA03580@ATHENA.MIT.EDU> obrooks@NSWC-WO.ARPA.UUCP writes:
>
>	Upon termination of the server we return to the shell prompt
>if we use the C shell. But if we use the Bourne or Korn shell we get
>blown off the system and have to login again. I suspect that the 
>Korn or Bourne shells are not catching a signal;

No, the real problem is a bug in X Windows. xinit will put its stdout
and stderr in non-blocking mode (so that error messages from the X
server don't block). That's fine, but when you exit, it doesn't return
them to normal mode. When ksh or the Bourne Shell try to read from
their stdin, the read returns right away with an error status. Since
the shell can't read any more commands from its stdin, it dies.

The C shell was apparently fixed to handle this but the real fix doesn't
belong in the shell; it should be in X.

In the meantime, Dave Korn has fixed ksh and it now works fine.
If you don't have source for ksh, try running csh from ksh before
you run xinit. I remember that worked for me.
    
    Eduardo Krell                   AT&T Bell Laboratories, Murray Hill, NJ

    UUCP: {ihnp4,ucbvax}!ulysses!ekrell		ARPA: ekrell@ulysses.att.com

turner@daisy.UUCP (Jim Turner) (04/09/88)

We have the exact same problem on our sun 386's (RoadRunners). In our case
its caused by the server closing stdin (or so we suspect) on exit, causing
the shell to get ^D's (EOF) and forcing the logout. Try set'ing ignoreeof
to see if that is the case with your users.

-- 
Laissez les bons temps rouler                     -  Queen Ida
...{decwrl|ucbvax}!imagen!atari!daisy!turner (James M. Turner)
Daisy Systems, 700 E. Middlefield Rd, P.O. Box 7006, 
Mountain View CA 94039-7006.                          (415)960-0123

guy@gorodish.Sun.COM (Guy Harris) (04/11/88)

> We have the exact same problem on our sun 386's (RoadRunners). In our case
> its caused by the server closing stdin (or so we suspect) on exit, causing
> the shell to get ^D's (EOF) and forcing the logout. Try set'ing ignoreeof
> to see if that is the case with your users.

Nope.

	1) If the server closes its standard input on exit, it has no effect
	   whatsoever on the server's parent, i.e. the shell.

	2) Even if the C shell's standard input *were* closed by this, this
	   would cause it to get an infinite sequence of EOFs and would
	   (obviously) completely prevent it from reading its standard input.
	   Setting "ignoreeof" wouldn't help.

	3) The scenario described by Eduardo Krell is correct (I know, because
	   I'm the one who discovered it).  The Xsun server puts its standard
	   output into no-delay mode, so that it won't hang trying to print a
	   message on the console (especially nasty if the console is an
	   "xterm" console window, where in order to display the message Xsun
	   has to paint some bits on the screen...).  This also affects the
	   standard input (no matter what version of UNIX you're using;
	   4BSD-style no-delay mode affects every descriptor that refers to
	   "/dev/console", but even S5-style no-delay mode affects all
	   descriptors "dup"ed from the one changed or from which that one was
	   "dup"ed, so it hits the standard input and error as well).

	   Unfortunately, it doesn't take it *out of* no-delay mode when it
	   exits.  The shell then tries to read from the no-delay descriptor
	   and gets an error (or EOF indication, with S5-style no-delay mode).
	   The C shell silently corrects for the former.  The Bourne and Korn
	   shells just give up and exit.

The C shell's silence is unfortunate; it means that the fact that Xsun was
broken wasn't discovered until people not using the C shell tried to run X11.

I fixed this on my machine by putting a call to "on_exit" in
"server/ddx/sun/sunInit.c" that tells it to call a routine just before exiting;
that routine will put the file descriptor back into normal mode.

------- sunInit.c -------
*** /tmp/da9065	Sun Apr 10 13:26:16 1988
--- sunInit.c	Mon Mar  7 22:37:31 1988
***************
*** 70,75 ****
--- 70,77 ----
  int sunSigIO = 0;	 /* For use with SetInputCheck */
  static int autoRepeatHandlersInstalled;	/* FALSE each time InitOutput called */
  
+ static int NonBlockConsoleOff();
+ 
  	/* What should this *really* be? */
  #define MOTION_BUFFER_SIZE 0
  
***************
*** 165,170 ****
--- 167,173 ----
       *	excess of error messages to hang the server in
       *	deadlock.  So.......
       */
+     on_exit(NonBlockConsoleOff, (char *)0);
      if (nonBlockConsole && (fcntl(2, F_SETFL, O_NDELAY) < 0)) {
  	perror("fcntl");
  	ErrorF("InitOutput: can't put stderr in non-block mode\n");
***************
*** 198,203 ****
--- 201,232 ----
  
      sunInitCursor();
      signal(SIGWINCH, SIG_IGN);
+ }
+ 
+ /*-
+  *-----------------------------------------------------------------------
+  * NonBlockConsoleOff --
+  *	Turn non-blocking mode on the console off, so you don't get logged
+  *	out when Xsun exits.
+  *
+  * Results:
+  *	None.
+  *
+  * Side Effects:
+  *	None.
+  *
+  *-----------------------------------------------------------------------
+  */
+ /*ARGSUSED*/
+ static
+ NonBlockConsoleOff(arg)
+     char	*arg;
+ {
+     register int i;
+ 
+     i = fcntl(2, F_SETFL, O_NDELAY);
+     if (i >= 0)
+ 	(void) fcntl(2, F_SETFL, i & O_NDELAY);
  }
  
  /*-