diff options
Diffstat (limited to 'tdm/backend/dm.c')
-rw-r--r-- | tdm/backend/dm.c | 173 |
1 files changed, 108 insertions, 65 deletions
diff --git a/tdm/backend/dm.c b/tdm/backend/dm.c index cd672f39a..861037032 100644 --- a/tdm/backend/dm.c +++ b/tdm/backend/dm.c @@ -51,6 +51,9 @@ from the copyright holder. # include <sys/vt.h> #endif +// Limited by the number of VTs configured into the kernel or 256, whichever is less +#define MAX_VT_NUMBER 48 + static void SigHandler( int n ); static int ScanConfigs( int force ); static void StartDisplays( void ); @@ -324,8 +327,9 @@ activateVT( int vt ) static void WakeDisplay( struct display *d ) { - if (d->status == textMode) + if (d->status == textMode) { d->status = (d->displayType & d_lifetime) == dReserve ? reserve : notRunning; + } } #endif @@ -511,7 +515,7 @@ StopToTTY( struct display *d ) if ((d->displayType & d_location) == dLocal) switch (d->status) { default: - rStopDisplay( d, DS_TEXTMODE | 0x100 ); + rStopDisplay(d, DS_TEXTMODE | 0x100); case reserve: case textMode: break; @@ -523,9 +527,11 @@ CheckTTYMode( void ) { struct display *d; - for (d = displays; d; d = d->next) - if (d->status == zombie) + for (d = displays; d; d = d->next) { + if (d->status == zombie) { return; + } + } SwitchToTty(); } @@ -793,12 +799,12 @@ processGPipe( struct display *d ) case G_Console: #ifdef HAVE_VTS if (*consoleTTYs) { /* sanity check against greeter */ - ForEachDisplay( StopToTTY ); + ForEachDisplay(StopToTTY); CheckTTYMode(); } #else if (*d->console) /* sanity check against greeter */ - rStopDisplay( d, DS_TEXTMODE ); + rStopDisplay(d, DS_TEXTMODE); #endif break; default: @@ -852,7 +858,6 @@ cancelShutdown( void ) RescanConfigs( TRUE ); } - static void ReapChildren( void ) { @@ -860,12 +865,11 @@ ReapChildren( void ) struct display *d; waitType status; - while ((pid = waitpid( -1, &status, WNOHANG )) > 0) - { + while ((pid = waitpid( -1, &status, WNOHANG)) > 0) { Debug( "manager wait returns pid %d sig %d core %d code %d\n", pid, waitSig( status ), waitCore( status ), waitCode( status ) ); /* SUPPRESS 560 */ - if ((d = FindDisplayByPid( pid ))) { + if ((d = FindDisplayByPid(pid))) { d->pid = -1; UnregisterInput( d->pipe.rfd ); GClosen (&d->pipe); @@ -953,41 +957,45 @@ ReapChildren( void ) if (d->follower) { d->follower->serverVT = d->serverVT; d->follower = 0; - } else { - int con = open( "/dev/console", O_RDONLY ); + } + else { + int con = open("/dev/console", O_RDONLY); if (con >= 0) { struct vt_stat vtstat; ioctl( con, VT_GETSTATE, &vtstat ); if (vtstat.v_active == d->serverVT) { int vt = 1; struct display *di; - for (di = displays; di; di = di->next) - if (di != d && di->serverVT) + for (di = displays; di; di = di->next) { + if (di != d && di->serverVT) { vt = di->serverVT; - for (di = displays; di; di = di->next) + } + } + for (di = displays; di; di = di->next) { if (di != d && di->serverVT && (di->userSess >= 0 || - di->status == remoteLogin)) + di->status == remoteLogin)) { vt = di->serverVT; - ioctl( con, VT_ACTIVATE, vt ); + } + } + ioctl(con, VT_ACTIVATE, vt); } - ioctl( con, VT_DISALLOCATE, d->serverVT ); - close( con ); + ioctl(con, VT_DISALLOCATE, d->serverVT); + close(con); } } d->serverVT = 0; + d->status = notRunning; } #endif - rStopDisplay( d, d->zstatus ); + rStopDisplay(d, d->zstatus); break; case phoenix: - Debug( "phoenix X server arises, restarting display %s\n", - d->name ); + Debug( "phoenix X server arises, restarting display %s\n", d->name ); d->status = notRunning; break; case remoteLogin: - Debug( "remote login X server for display %s exited\n", - d->name ); + Debug( "remote login X server for display %s exited\n", d->name ); d->status = ((d->displayType & d_lifetime) == dReserve) ? reserve : notRunning; break; @@ -1032,11 +1040,14 @@ wouldShutdown( void ) struct display *d; if (sdRec.force != SHUT_CANCEL) { - if (sdRec.force == SHUT_FORCEMY) - for (d = displays; d; d = d->next) + if (sdRec.force == SHUT_FORCEMY) { + for (d = displays; d; d = d->next) { if (d->status == remoteLogin || - (d->userSess >= 0 && d->userSess != sdRec.uid)) + (d->userSess >= 0 && d->userSess != sdRec.uid)) { return 0; + } + } + } return 1; } return !AnyActiveDisplays(); @@ -1078,7 +1089,9 @@ SigHandler( int n ) int olderrno = errno; char buf = (char)n; /* Debug( "caught signal %d\n", n ); this hangs in syslog() */ - write( signalFds[1], &buf, 1 ); + if (write(signalFds[1], &buf, 1) != 1) { + // ERROR + } #ifdef __EMX__ (void)Signal( n, SigHandler ); #endif @@ -1178,23 +1191,27 @@ MainLoop( void ) break; case SIGCHLD: ReapChildren(); - if (!Stopping && autoRescan) + if (!Stopping && autoRescan) { RescanConfigs( FALSE ); + } break; case SIGUSR1: if (startingServer && - startingServer->serverStatus == starting) + startingServer->serverStatus == starting) { StartServerSuccess(); + } break; } continue; } #ifdef XDMCP - if (ProcessListenSockets( &reads )) + if (ProcessListenSockets( &reads )) { continue; + } #endif /* XDMCP */ - if (handleCtrl( &reads, 0 )) + if (handleCtrl( &reads, 0 )) { continue; + } /* Must be last (because of the breaks)! */ again: for (d = displays; d; d = d->next) { @@ -1216,18 +1233,21 @@ MainLoop( void ) static void CheckDisplayStatus( struct display *d ) { - if ((d->displayType & d_origin) == dFromFile && !d->stillThere) + if ((d->displayType & d_origin) == dFromFile && !d->stillThere) { StopDisplay( d ); + } else if ((d->displayType & d_lifetime) == dReserve && - d->status == running && d->userSess < 0 && !d->idleTimeout) - rStopDisplay( d, DS_RESERVE ); - else if (d->status == notRunning) + d->status == running && d->userSess < 0 && !d->idleTimeout) { + rStopDisplay(d, DS_RESERVE); + } + else if (d->status == notRunning) { if (LoadDisplayResources( d ) < 0) { LogError( "Unable to read configuration for display %s; " "stopping it.\n", d->name ); StopDisplay( d ); return; } + } } static void @@ -1240,27 +1260,37 @@ KickDisplay( struct display *d ) } #ifdef HAVE_VTS -static int active_vts; +static unsigned long active_vts; -static int -GetBusyVTs( void ) +static unsigned long +GetBusyVTs(void) { struct vt_stat vtstat; int con; if (active_vts == -1) { + unsigned short next_available_vt = 0; vtstat.v_state = 0; if ((con = open( "/dev/console", O_RDONLY )) >= 0) { - ioctl( con, VT_GETSTATE, &vtstat ); - close( con ); + ioctl(con, VT_GETSTATE, &vtstat); + ioctl(con, VT_OPENQRY, &next_available_vt); + close(con); } active_vts = vtstat.v_state; + if (next_available_vt > 0xf) { + // Assume all VTs less than the next available VT are busy + // This is due to limitations in the Linux console driver + int i; + for (i = 0x10; i < next_available_vt; i++) { + active_vts |= (1 << i); + } + } } return active_vts; } static void -AllocateVT( struct display *d ) +AllocateVT(struct display *d) { struct display *cd; int i, tvt, volun; @@ -1268,31 +1298,37 @@ AllocateVT( struct display *d ) if ((d->displayType & d_location) == dLocal && d->status == notRunning && !d->serverVT && d->reqSrvVT >= 0) { - if (d->reqSrvVT && d->reqSrvVT < 16) + if (d->reqSrvVT && d->reqSrvVT < MAX_VT_NUMBER) { d->serverVT = d->reqSrvVT; + } else { for (i = tvt = 0;;) { if (serverVTs[i]) { - tvt = atoi( serverVTs[i++] ); + tvt = atoi(serverVTs[i++]); volun = 0; if (tvt < 0) { tvt = -tvt; volun = 1; } - if (!tvt || tvt >= 16) + if (!tvt || tvt >= MAX_VT_NUMBER) { continue; - } else { - if (++tvt >= 16) + } + } + else { + if (++tvt >= MAX_VT_NUMBER) { break; + } volun = 1; } for (cd = displays; cd; cd = cd->next) { if (cd->reqSrvVT == tvt && /* protect from lusers */ - (cd->status != zombie || cd->zstatus != DS_REMOVE)) + (cd->status != zombie || cd->zstatus != DS_REMOVE)) { goto next; + } if (cd->serverVT == tvt) { - if (cd->status != zombie || cd->zstatus == DS_REMOTE) + if (cd->status != zombie || cd->zstatus == DS_REMOTE) { goto next; + } if (!cd->follower) { d->serverVT = -1; cd->follower = d; @@ -1300,7 +1336,7 @@ AllocateVT( struct display *d ) } } } - if (!volun || !((1 << tvt) & GetBusyVTs())) { + if (!volun || !((1 << (unsigned long)tvt) & GetBusyVTs())) { d->serverVT = tvt; return; } @@ -1426,27 +1462,34 @@ rStopDisplay( struct display *d, int endState ) AbortStartServer( d ); d->idleTimeout = 0; if (d->serverPid != -1 || d->pid != -1) { - if (d->pid != -1) + if (d->pid != -1) { TerminateProcess( d->pid, SIGTERM ); - if (d->serverPid != -1) + } + if (d->serverPid != -1) { TerminateProcess( d->serverPid, d->termSignal ); + } d->status = zombie; d->zstatus = endState & 0xff; Debug( " zombiefied\n" ); - } else if (endState == DS_TEXTMODE) { + } + else if (endState == DS_TEXTMODE) { #ifdef HAVE_VTS d->status = textMode; CheckTTYMode(); - } else if (endState == (DS_TEXTMODE | 0x100)) { + } + else if (endState == (DS_TEXTMODE | 0x100)) { d->status = textMode; #else SwitchToTty( d ); #endif - } else if (endState == DS_RESERVE) + } + else if (endState == DS_RESERVE) { d->status = reserve; + } #ifdef XDMCP - else if (endState == DS_REMOTE) + else if (endState == DS_REMOTE) { StartRemoteLogin( d ); + } #endif else { #ifndef HAVE_VTS @@ -1459,7 +1502,7 @@ rStopDisplay( struct display *d, int endState ) void StopDisplay( struct display *d ) { - rStopDisplay( d, DS_REMOVE ); + rStopDisplay(d, DS_REMOVE); } static void @@ -1476,8 +1519,7 @@ ExitDisplay( goodExit = TRUE; } - Debug( "ExitDisplay %s, " - "endState = %d, serverCmd = %d, GoodExit = %d\n", + Debug( "ExitDisplay %s, endState = %d, serverCmd = %d, GoodExit = %d\n", d->name, endState, serverCmd, goodExit ); d->userSess = -1; @@ -1511,18 +1553,19 @@ ExitDisplay( he->sdRec.osname = 0; } } - if (d->status == zombie) - rStopDisplay( d, d->zstatus ); + if (d->status == zombie) { + rStopDisplay(d, d->zstatus); + } else { if (Stopping) { StopDisplay( d ); return; } if (endState != DS_RESTART || - (d->displayType & d_origin) != dFromFile) - { - rStopDisplay( d, endState ); - } else { + (d->displayType & d_origin) != dFromFile) { + rStopDisplay(d, endState); + } + else { if (serverCmd == XS_RETRY) { if ((d->displayType & d_location) == dLocal) { if (he->lastExit - d->lastStart < 120) { |