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