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."