49
49
time_t serverTimeout = TO_INF;
52
prepareServerArgv( struct display *d, const char *args )
52
prepareServerArgv(struct display *d, const char *args)
59
if (!(argv = parseArgs( 0, d->serverCmd )) ||
60
!(argv = addStrArr( argv, d->name, -1 )))
64
!(argv = addStrArr( argv, vtstr,
65
sprintf( vtstr, "vt%d", d->serverVT ) )))
68
if (!(argv = parseArgs( argv, args )))
71
if (!changeUser( d->serverUID, d->authFile ))
59
if (!(argv = parseArgs(0, d->serverCmd)) ||
60
!(argv = addStrArr(argv, d->name, -1)))
64
!(argv = addStrArr(argv, vtstr,
65
sprintf(vtstr, "vt%d", d->serverVT))))
68
if (!(argv = parseArgs(argv, args)))
71
if (!changeUser(d->serverUID, d->authFile))
78
startServerOnce( void )
80
struct display *d = startingServer;
83
debug( "startServerOnce for %s, try %d\n", d->name, ++d->startTries );
84
d->serverStatus = starting;
85
switch (Fork( &d->serverPid )) {
87
argv = prepareServerArgv( d, d->serverArgsLocal );
89
if (!(argv = addStrArr( argv, "-auth", 5 )) ||
90
!(argv = addStrArr( argv, d->authFile, -1 )))
93
debug( "exec %\"[s\n", argv );
95
* give the server SIGUSR1 ignored,
96
* it will notice that and send SIGUSR1
99
(void)Signal( SIGUSR1, SIG_IGN );
100
(void)execv( argv[0], argv );
102
/* Let's try again with a standard path */
103
argv[0] = (char *)realloc(argv[0], strlen("/usr/bin/X") + 1);
104
if (argv[0] != NULL) {
105
argv[0] = "/usr/bin/X";
106
debug( "exec %\"[s\n", argv );
107
(void)execv( argv[0], argv );
108
logError( "X server %\"s cannot be executed\n", argv[0] );
111
logError( "X server %\"s cannot be executed\n", argv[0] );
114
logError( "X server fork failed\n" );
118
debug( "X server forked, pid %d\n", d->serverPid );
119
serverTimeout = d->serverTimeout + now;
125
startServer( struct display *d )
133
abortStartServer( struct display *d )
135
if (startingServer == d)
137
if (d->serverStatus != ignore)
139
d->serverStatus = ignore;
140
serverTimeout = TO_INF;
141
debug( "aborting X server start\n" );
80
struct display *d = startingServer;
83
debug("startServerOnce for %s, try %d\n", d->name, ++d->startTries);
84
d->serverStatus = starting;
85
switch (Fork(&d->serverPid)) {
87
argv = prepareServerArgv(d, d->serverArgsLocal);
89
if (!(argv = addStrArr(argv, "-auth", 5)) ||
90
!(argv = addStrArr(argv, d->authFile, -1)))
93
debug("exec %\"[s\n", argv);
95
* give the server SIGUSR1 ignored,
96
* it will notice that and send SIGUSR1
99
(void)Signal(SIGUSR1, SIG_IGN);
100
(void)execv(argv[0], argv);
102
/* Let's try again with a standard path */
103
argv[0] = (char *)realloc(argv[0], strlen("/usr/bin/X") + 1);
104
if (argv[0] != NULL) {
105
argv[0] = "/usr/bin/X";
106
debug( "exec %\"[s\n", argv );
107
(void)execv( argv[0], argv );
108
logError( "X server %\"s cannot be executed\n", argv[0] );
111
logError("X server %\"s cannot be executed\n", argv[0]);
114
logError("X server fork failed\n");
118
debug("X server forked, pid %d\n", d->serverPid);
119
serverTimeout = d->serverTimeout + now;
125
startServer(struct display *d)
133
abortStartServer(struct display *d)
135
if (startingServer == d) {
136
if (d->serverStatus != ignore) {
137
d->serverStatus = ignore;
138
serverTimeout = TO_INF;
139
debug("aborting X server start\n");
148
146
startServerSuccess()
150
struct display *d = startingServer;
151
d->serverStatus = ignore;
152
serverTimeout = TO_INF;
153
debug( "X server ready, starting session\n" );
148
struct display *d = startingServer;
149
d->serverStatus = ignore;
150
serverTimeout = TO_INF;
151
debug("X server ready, starting session\n");
158
156
startServerFailed()
160
struct display *d = startingServer;
161
if (!d->serverAttempts || d->startTries < d->serverAttempts) {
162
d->serverStatus = pausing;
163
serverTimeout = d->openDelay + now;
165
d->serverStatus = ignore;
166
serverTimeout = TO_INF;
168
logError( "X server for display %s cannot be started,"
169
" session disabled\n", d->name );
158
struct display *d = startingServer;
159
if (!d->serverAttempts || d->startTries < d->serverAttempts) {
160
d->serverStatus = pausing;
161
serverTimeout = d->openDelay + now;
163
d->serverStatus = ignore;
164
serverTimeout = TO_INF;
166
logError("X server for display %s cannot be started,"
167
" session disabled\n", d->name);
175
173
startServerTimeout()
177
struct display *d = startingServer;
178
switch (d->serverStatus) {
181
break; /* cannot happen */
183
logError( "X server startup timeout, terminating\n" );
184
kill( d->serverPid, d->termSignal );
185
d->serverStatus = d->termSignal == SIGKILL ? killed : terminated;
186
serverTimeout = d->serverTimeout + now;
189
logInfo( "X server termination timeout, killing\n" );
190
kill( d->serverPid, SIGKILL );
191
d->serverStatus = killed;
192
serverTimeout = 10 + now;
195
logInfo( "X server is stuck in D state; leaving it alone\n" );
175
struct display *d = startingServer;
176
switch (d->serverStatus) {
179
break; /* cannot happen */
181
logError("X server startup timeout, terminating\n");
182
kill(d->serverPid, d->termSignal);
183
d->serverStatus = d->termSignal == SIGKILL ? killed : terminated;
184
serverTimeout = d->serverTimeout + now;
187
logInfo("X server termination timeout, killing\n");
188
kill(d->serverPid, SIGKILL);
189
d->serverStatus = killed;
190
serverTimeout = 10 + now;
193
logInfo("X server is stuck in D state; leaving it alone\n");
231
getRemoteAddress( struct display *d, int fd )
229
getRemoteAddress(struct display *d, int fd)
234
int len = sizeof(buf);
232
int len = sizeof(buf);
235
233
#ifdef STREAMSCONN
239
XdmcpDisposeARRAY8( &d->peer );
237
XdmcpDisposeARRAY8(&d->peer);
240
238
#ifdef STREAMSCONN
241
netb.maxlen = sizeof(buf);
243
t_getname( fd, &netb, REMOTENAME );
245
/* lucky for us, t_getname returns something that looks like a sockaddr */
239
netb.maxlen = sizeof(buf);
241
t_getname(fd, &netb, REMOTENAME);
243
/* lucky for us, t_getname returns something that looks like a sockaddr */
247
getpeername( fd, (struct sockaddr *)buf, (void *)&len );
245
getpeername(fd, (struct sockaddr *)buf, (void *)&len);
249
if (len && XdmcpAllocARRAY8( &d->peer, len ))
250
memmove( d->peer.data, buf, len );
251
debug( "got remote address %s %d\n", d->name, d->peer.length );
247
if (len && XdmcpAllocARRAY8(&d->peer, len))
248
memmove(d->peer.data, buf, len);
249
debug("got remote address %s %d\n", d->name, d->peer.length);
254
252
#endif /* XDMCP */
257
openErrorHandler( Display *dspl ATTR_UNUSED )
255
openErrorHandler(Display *dspl ATTR_UNUSED)
259
logError( "IO Error in XOpenDisplay\n" );
260
exit( EX_OPENFAILED_DPY );
257
logError("IO Error in XOpenDisplay\n");
258
exit(EX_OPENFAILED_DPY);
266
waitForServer( struct display *d )
264
waitForServer(struct display *d)
273
(void)Signal( SIGALRM, abortOpen );
274
(void)alarm( (unsigned)d->openTimeout );
275
if (!Setjmp( openAbort )) {
276
debug( "before XOpenDisplay(%s)\n", d->name );
278
(void)XSetIOErrorHandler( openErrorHandler );
279
dpy = XOpenDisplay( d->name );
271
(void)Signal(SIGALRM, abortOpen);
272
(void)alarm((unsigned)d->openTimeout);
273
if (!Setjmp(openAbort)) {
274
debug("before XOpenDisplay(%s)\n", d->name);
276
(void)XSetIOErrorHandler(openErrorHandler);
277
dpy = XOpenDisplay(d->name);
280
278
#ifdef STREAMSCONN
282
/* For some reason, the next XOpenDisplay we do is
283
going to fail, so we might as well get that out
284
of the way. There is something broken here. */
285
Display *bogusDpy = XOpenDisplay( d->name );
286
debug( "bogus XOpenDisplay %s\n",
287
bogusDpy ? "succeeded" : "failed" );
288
if (bogusDpy) XCloseDisplay( bogusDpy ); /* just in case */
280
/* For some reason, the next XOpenDisplay we do is
281
going to fail, so we might as well get that out
282
of the way. There is something broken here. */
283
Display *bogusDpy = XOpenDisplay(d->name);
284
debug("bogus XOpenDisplay %s\n",
285
bogusDpy ? "succeeded" : "failed");
287
XCloseDisplay(bogusDpy); /* just in case */
291
(void)alarm( (unsigned)0 );
292
(void)Signal( SIGALRM, SIG_DFL );
293
(void)XSetIOErrorHandler( (int (*)( Display * )) 0 );
294
debug( "after XOpenDisplay(%s)\n", d->name );
290
(void)alarm((unsigned)0);
291
(void)Signal(SIGALRM, SIG_DFL);
292
(void)XSetIOErrorHandler((int (*)(Display *)) 0);
293
debug("after XOpenDisplay(%s)\n", d->name);
297
if ((d->displayType & d_location) == dForeign)
298
getRemoteAddress( d, ConnectionNumber( dpy ) );
296
if ((d->displayType & d_location) == dForeign)
297
getRemoteAddress(d, ConnectionNumber(dpy));
300
registerCloseOnFork( ConnectionNumber( dpy ) );
303
debug( "OpenDisplay(%s) attempt %d failed: %m\n", d->name, i + 1 );
304
sleep( (unsigned)d->openDelay );
306
logError( "Hung in XOpenDisplay(%s), aborting\n", d->name );
307
(void)Signal( SIGALRM, SIG_DFL );
310
} while (++i < d->openRepeat);
311
logError( "Cannot connect to %s, giving up\n", d->name );
312
exit( EX_OPENFAILED_DPY );
299
registerCloseOnFork(ConnectionNumber(dpy));
302
debug("OpenDisplay(%s) attempt %d failed: %m\n", d->name, i + 1);
303
sleep((unsigned)d->openDelay);
305
logError("Hung in XOpenDisplay(%s), aborting\n", d->name);
306
(void)Signal(SIGALRM, SIG_DFL);
309
} while (++i < d->openRepeat);
310
logError("Cannot connect to %s, giving up\n", d->name);
311
exit(EX_OPENFAILED_DPY);
317
resetServer( struct display *d )
316
resetServer(struct display *d)
319
if (dpy && (d->displayType & d_origin) != dFromXDMCP)
318
if (dpy && (d->displayType & d_origin) != dFromXDMCP)
324
323
static Jmp_buf pingTime;
329
Longjmp( pingTime, 1 );
328
Longjmp(pingTime, 1);
334
pingLostIOErr( Display *dspl ATTR_UNUSED )
333
pingLostIOErr(Display *dspl ATTR_UNUSED)
342
pingLostSig( int n ATTR_UNUSED )
341
pingLostSig(int n ATTR_UNUSED)
348
pingServer( struct display *d )
347
pingServer(struct display *d)
350
int (*oldError)( Display * );
351
void (*oldSig)( int );
349
int (*oldError)(Display *);
354
oldError = XSetIOErrorHandler( pingLostIOErr );
355
oldAlarm = alarm( 0 );
356
oldSig = Signal( SIGALRM, pingLostSig );
357
(void)alarm( d->pingTimeout * 60 );
358
if (!Setjmp( pingTime )) {
359
debug( "ping X server\n" );
362
debug( "X server dead\n" );
364
(void)Signal( SIGALRM, SIG_DFL );
365
XSetIOErrorHandler( oldError );
369
(void)Signal( SIGALRM, oldSig );
370
(void)alarm( oldAlarm );
371
debug( "X server alive\n" );
372
XSetIOErrorHandler( oldError );
353
oldError = XSetIOErrorHandler(pingLostIOErr);
355
oldSig = Signal(SIGALRM, pingLostSig);
356
(void)alarm(d->pingTimeout * 60);
357
if (!Setjmp(pingTime)) {
358
debug("ping X server\n");
361
debug("X server dead\n");
363
(void)Signal(SIGALRM, SIG_DFL);
364
XSetIOErrorHandler(oldError);
368
(void)Signal(SIGALRM, oldSig);
369
(void)alarm(oldAlarm);
370
debug("X server alive\n");
371
XSetIOErrorHandler(oldError);