|
|
1.1 ! root 1: #ifndef lint ! 2: static char *rcsid_xinit_c = "$Header: xinit.c,v 11.2 87/08/07 14:37:54 toddb Exp $"; ! 3: #endif lint ! 4: #include <X11/copyright.h> ! 5: ! 6: /* Copyright Massachusetts Institute of Technology 1986 */ ! 7: ! 8: #include <X11/Xlib.h> ! 9: #include <stdio.h> ! 10: #include <ctype.h> ! 11: #include <signal.h> ! 12: #include <sys/time.h> /* unused but resource.h needs it */ ! 13: #include <sys/resource.h> ! 14: #include <sys/wait.h> ! 15: #include <errno.h> ! 16: ! 17: #define TRUE 1 ! 18: #define FALSE 0 ! 19: #define OK_EXIT 0 ! 20: #define ERR_EXIT 1 ! 21: #define DEFAULT_SERVER "X" ! 22: #define DEFAULT_DISPLAY ":0" ! 23: char *default_client[] = { ! 24: "xterm", "=+1+1", "-n", "login", ! 25: #ifdef sun ! 26: "-C", ! 27: #endif ! 28: "unix:0", NULL}; ! 29: char *server[100]; ! 30: char *client[100]; ! 31: char *displayNum; ! 32: char *program; ! 33: Display *xd; /* server connection */ ! 34: union wait status; ! 35: int serverpid = -1; ! 36: int clientpid = -1; ! 37: extern int errno; ! 38: ! 39: sigCatch(sig) ! 40: int sig; ! 41: { ! 42: signal(SIGQUIT, SIG_IGN); ! 43: signal(SIGINT, SIG_IGN); ! 44: Error("signal %d\n", sig); ! 45: shutdown(serverpid, clientpid); ! 46: exit(1); ! 47: } ! 48: ! 49: main(argc, argv) ! 50: int argc; ! 51: register char **argv; ! 52: { ! 53: register char **sptr = server; ! 54: register char **cptr = client; ! 55: register char **ptr; ! 56: int pid, i; ! 57: ! 58: program = *argv++; ! 59: argc--; ! 60: ! 61: /* ! 62: * copy the client args. ! 63: */ ! 64: if (argc == 0 || (**argv != '/' && !isalpha(**argv))) ! 65: for (ptr = default_client; *ptr; ) ! 66: *cptr++ = *ptr++; ! 67: while (argc && strcmp(*argv, "--")) { ! 68: *cptr++ = *argv++; ! 69: argc--; ! 70: } ! 71: *cptr = NULL; ! 72: if (argc) { ! 73: argv++; ! 74: argc--; ! 75: } ! 76: ! 77: /* ! 78: * Copy the server args. ! 79: */ ! 80: if (argc == 0 || (**argv != '/' && !isalpha(**argv))) { ! 81: *sptr++ = DEFAULT_SERVER; ! 82: } else { ! 83: *sptr++ = *argv++; ! 84: argc--; ! 85: } ! 86: if (argc > 0 && (argv[0][0] == ':' && isdigit(argv[0][1]))) ! 87: displayNum = *argv; ! 88: else ! 89: displayNum = *sptr++ = DEFAULT_DISPLAY; ! 90: while (--argc >= 0) ! 91: *sptr++ = *argv++; ! 92: *sptr = NULL; ! 93: ! 94: /* ! 95: * Start the server and client. ! 96: */ ! 97: signal(SIGQUIT, sigCatch); ! 98: signal(SIGINT, sigCatch); ! 99: if ((serverpid = startServer(server)) > 0 ! 100: && (clientpid = startClient(client)) > 0) { ! 101: pid = -1; ! 102: while (pid != clientpid && pid != serverpid) ! 103: pid = wait(NULL); ! 104: } ! 105: signal(SIGQUIT, SIG_IGN); ! 106: signal(SIGINT, SIG_IGN); ! 107: ! 108: shutdown(serverpid, clientpid); ! 109: ! 110: if (serverpid < 0 || clientpid < 0) ! 111: exit(ERR_EXIT); ! 112: exit(OK_EXIT); ! 113: } ! 114: ! 115: ! 116: /* ! 117: * waitforserver - wait for X server to start up ! 118: */ ! 119: ! 120: waitforserver(serverpid) ! 121: int serverpid; ! 122: { ! 123: int ncycles = 120; /* # of cycles to wait */ ! 124: int cycles; /* Wait cycle count */ ! 125: char display[100]; /* Display name */ ! 126: ! 127: strcpy(display, "unix"); ! 128: strcat(display, displayNum); ! 129: for (cycles = 0; cycles < ncycles; cycles++) { ! 130: if (xd = XOpenDisplay(display)) { ! 131: return(TRUE); ! 132: } ! 133: else { ! 134: if (!processTimeout(serverpid, 1, "server to start")) ! 135: return(FALSE); ! 136: } ! 137: } ! 138: ! 139: return(FALSE); ! 140: } ! 141: ! 142: /* ! 143: * return TRUE if we timeout waiting for pid to exit, FALSE otherwise. ! 144: */ ! 145: processTimeout(pid, timeout, string) ! 146: int pid, timeout; ! 147: char *string; ! 148: { ! 149: int i = 0, pidfound = -1; ! 150: static char *laststring; ! 151: ! 152: for (;;) { ! 153: if ((pidfound = wait3(&status, WNOHANG, NULL)) == pid) ! 154: break; ! 155: if (timeout) { ! 156: if (i == 0 && string != laststring) ! 157: fprintf(stderr, "\nwaiting for %s ", string); ! 158: else ! 159: fprintf(stderr, ".", string); ! 160: fflush(stderr); ! 161: } ! 162: if (timeout) ! 163: sleep (1); ! 164: if (++i > timeout) ! 165: break; ! 166: } ! 167: laststring = string; ! 168: return( pid != pidfound ); ! 169: } ! 170: ! 171: Error(fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9) ! 172: char *fmt; ! 173: { ! 174: extern char *sys_errlist[]; ! 175: ! 176: fprintf(stderr, "%s: ", program); ! 177: if (errno) ! 178: fprintf(stderr, "%s: ", sys_errlist[ errno ]); ! 179: fprintf(stderr, fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9); ! 180: } ! 181: ! 182: Fatal(fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9) ! 183: char *fmt; ! 184: { ! 185: Error(fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9); ! 186: exit(ERR_EXIT); ! 187: } ! 188: ! 189: startServer(server) ! 190: char *server[]; ! 191: { ! 192: int serverpid; ! 193: ! 194: serverpid = vfork(); ! 195: switch(serverpid) { ! 196: case 0: ! 197: close(0); ! 198: close(1); ! 199: ! 200: /* ! 201: * prevent server from getting sighup from vhangup() ! 202: * if client is xterm -L ! 203: */ ! 204: setpgrp(0,0); ! 205: ! 206: execvp(server[0], server); ! 207: Fatal("Server \"%s\" died on startup\n", server[0]); ! 208: break; ! 209: case -1: ! 210: break; ! 211: default: ! 212: /* ! 213: * don't nice server ! 214: */ ! 215: setpriority( PRIO_PROCESS, serverpid, -1 ); ! 216: ! 217: errno = 0; ! 218: if (! processTimeout(serverpid, 0, "")) { ! 219: serverpid = -1; ! 220: break; ! 221: } ! 222: /* ! 223: * kludge to avoid race with TCP, giving server time to ! 224: * set his socket options before we try to open it ! 225: */ ! 226: sleep(5); ! 227: ! 228: if (waitforserver(serverpid) == 0) { ! 229: Error("Can't connect to server\n"); ! 230: shutdown(serverpid, -1); ! 231: serverpid = -1; ! 232: } ! 233: break; ! 234: } ! 235: ! 236: return(serverpid); ! 237: } ! 238: ! 239: startClient(client) ! 240: char *client[]; ! 241: { ! 242: int clientpid; ! 243: ! 244: if ((clientpid = vfork()) == 0) { ! 245: setreuid(-1, -1); ! 246: setpgrp(0, getpid()); ! 247: execvp(client[0], client); ! 248: Fatal("Client \"%s\" died on startup\n", client[0]); ! 249: } ! 250: return (clientpid); ! 251: } ! 252: ! 253: shutdown(serverpid, clientpid) ! 254: int serverpid, clientpid; ! 255: { ! 256: /* have kept display opened, so close it now */ ! 257: if (clientpid > 0) { ! 258: XCloseDisplay(xd); ! 259: ! 260: /* HUP all local clients to allow them to clean up */ ! 261: errno = 0; ! 262: if (killpg(clientpid, SIGHUP) != 0) ! 263: Error("can't killpg(%d, SIGHUP) for client\n", ! 264: clientpid); ! 265: } ! 266: ! 267: if (serverpid < 0) ! 268: return; ! 269: errno = 0; ! 270: if (kill(serverpid, SIGTERM) < 0) { ! 271: if (errno == EPERM) ! 272: Fatal("Can't kill server\n"); ! 273: if (errno == ESRCH) ! 274: return; ! 275: } ! 276: if (! processTimeout(serverpid, 10, "server to terminate")) ! 277: return; ! 278: ! 279: fprintf(stderr, "timeout... send SIGKILL"); ! 280: fflush(stderr); ! 281: errno = 0; ! 282: if (kill(serverpid, SIGKILL) < 0) { ! 283: if (errno == ESRCH) ! 284: return; ! 285: } ! 286: if (processTimeout(serverpid, 3, "server to die")) ! 287: Fatal("Can't kill server\n"); ! 288: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.