[comp.windows.x] Modification to xinit

clyde@ut-ngp.UUCP (03/25/87)

Here are some changes I found useful for xinit.  There are:
	1. Set up all clients in a unique process group.  When the
	   client returns, send a SIGHUP to that process group so that
	   any other lingering clients can clean up and exit.
	2. Wait for the server to really start up.  On loaded machines
	   (such as my SUN when sendmail fires up), the X server may take
	   several seconds to start up, and xinit's "I'll give the server
	   a few seconds to get going" attitude fails.  Only after the server
	   is responding to clients is the client command started up.

These mods tend to make startup and shutdown take a bit more time, but
it's worth it to me to alleviate some race conditions.  Of course, there
are still some 'Well that should be enough time' sleeps in the code, but
they don't seem to be troublesome.

---------------- Cut here ------------
*** /u/X/xinit/xinit.c	Mon Dec  1 18:51:40 1986
--- xinit.c	Tue Mar 24 14:40:45 1987
***************
*** 62,68
  	    perror(server[0]);
  	    exit(1);
  	}
! 	sleep(5);
  	if ((clientpid = fork()) == 0) {
  	    execvp(client[0], client);
  	    perror(client[0]);

--- 62,72 -----
  	    perror(server[0]);
  	    exit(1);
  	}
! 	if (waitforserver() == 0) {
! 		perror("Server wait");
! 		kill(serverpid, SIGKILL);
! 		exit(1);
! 	}
  	if ((clientpid = fork()) == 0) {
  	    setpgrp(0, getpid());
  	    execvp(client[0], client);
***************
*** 64,69
  	}
  	sleep(5);
  	if ((clientpid = fork()) == 0) {
  	    execvp(client[0], client);
  	    perror(client[0]);
  	    exit(1);

--- 68,74 -----
  		exit(1);
  	}
  	if ((clientpid = fork()) == 0) {
+ 	    setpgrp(0, getpid());
  	    execvp(client[0], client);
  	    perror(client[0]);
  	    exit(1);
***************
*** 74,80
  	    exit(1);
  	}
  	while (((pid = wait(NULL)) != clientpid) && (pid != serverpid)) ;
! 	kill(clientpid, SIGKILL);
  	if (!kill(serverpid, SIGHUP)) {
  	    sleep(1);
  	    kill(serverpid, SIGKILL);

--- 79,90 -----
  	    exit(1);
  	}
  	while (((pid = wait(NULL)) != clientpid) && (pid != serverpid)) ;
! 	/* HUP all local clients to allow them to clean up */
! 	if (killpg(clientpid, SIGHUP) == 0)
! 		sleep(2);
! 	/* Murder the local clients */
! 	killpg(clientpid, SIGKILL);
! 	/* Now tell the server to clean up */
  	if (!kill(serverpid, SIGHUP)) {
  	    sleep(1);
  	    kill(serverpid, SIGKILL);	/* Now make server die */
***************
*** 77,82
  	kill(clientpid, SIGKILL);
  	if (!kill(serverpid, SIGHUP)) {
  	    sleep(1);
! 	    kill(serverpid, SIGKILL);
  	}
  }

--- 87,93 -----
  	/* Now tell the server to clean up */
  	if (!kill(serverpid, SIGHUP)) {
  	    sleep(1);
! 	    kill(serverpid, SIGKILL);	/* Now make server die */
  	}
  	exit(0);
  }
***************
*** 79,82
  	    sleep(1);
  	    kill(serverpid, SIGKILL);
  	}
  }

--- 89,121 -----
  	    sleep(1);
  	    kill(serverpid, SIGKILL);	/* Now make server die */
  	}
+ 	exit(0);
+ }
+ 
+ 
+ /*
+  *	waitforserver - wait for X server to start up
+  */
+ #include <X/Xlib.h>
+ int	ncycles	 = 120;
+ 
+ waitforserver()
+ {
+ 	int	cycles;			/* Wait cycle count */
+ 	Display *xd;			/* Temp */
+ 	char	*display = "unix:0",	/* Display name */
+ 		*envd;			/* From environment */
+ 	extern char	*getenv();
+ 
+ 	if (envd = getenv("DISPLAY"))
+ 		display = envd;
+ 	for (cycles = 0; cycles < ncycles; cycles++) {
+ 		if (xd = XOpenDisplay(display)) {
+ 			XCloseDisplay(xd);
+ 			return(1);
+ 		}
+ 		else
+ 			sleep(1);
+ 	}
+ 	return(0);
  }
-- 
Shouter-To-Dead-Parrots @ Univ. of Texas Computation Center; Austin, Texas  
	clyde@ngp.cc.utexas.edu; ...!ut-sally!ut-ngp!clyde
"It's a sort of a threat, you see.  I've never been very good at them
myself, but I've told they can be very effective."