From 2e089ae2e0546212adc70828b4c91a9c234d4a99 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 13 May 2019 16:09:55 +0200 Subject: Support --min-idle Requires a minimum amount of user idle time before performing a scheduled reboot/poweroff if a user is logged on. --- src/main.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index 032aa27..cd18aa4 100644 --- a/src/main.c +++ b/src/main.c @@ -36,6 +36,7 @@ static struct { time_t deadline; // MONOTONIC; 0 = none, or last one was disarmed and time elapsed past deadline enum Shutdown action; bool disarmed; + bool force; } nextAction; // Config via command line @@ -49,6 +50,7 @@ static struct { int saverTimeout; int dpmsTimeout; int gracePeriod; + int minIdle; } config; static time_t combineTime( const time_t now, const struct time * time ); @@ -94,6 +96,7 @@ int main( int argc, char **argv ) for ( ;; ) { int sleepTime = defaultSleep; const int count = getUserList( users, USERS ); + int minIdleTime = -1; for ( idx = 0; idx < count; ++idx ) { struct user * const usr = &users[idx]; if ( !usr->mark ) { @@ -145,7 +148,7 @@ int main( int argc, char **argv ) want = SCREEN_OFF; } if ( want != SCREEN_UNKNOWN && screen.screenStandby != want ) { - printf( "#### Powering %s %s.\n", usr->display, want == SCREEN_ON ? "ON" : "OFF" ); + //printf( "#### Powering %s %s.\n", usr->display, want == SCREEN_ON ? "ON" : "OFF" ); setScreenDpms( usr->xauth, usr->display, want ); } } @@ -175,6 +178,10 @@ int main( int argc, char **argv ) } //printf( "Have User %d: %s Locked %d (%+d) Idle %d (%+d) -- Leader: %d\n", idx, usr->user, (int)usr->lockTime, usr->lockTimeOffset, (int)usr->lastActivity, usr->lastActivityOffset, (int)usr->sessionLeader ); const int idleTime = NOW - usr->lastActivity; + // Min of all sessions + if ( idleTime >= 0 && idleTime < minIdleTime ) { + minIdleTime = idleTime; + } // See if we need to shorten sleep time for a pending session kill // or warn the user about an imminent session kill // or whether the screen saver is supposed to activate @@ -201,7 +208,7 @@ int main( int argc, char **argv ) } // End loop over users const time_t monoNOW = now(); // See if any reboot or poweroff is due (if none is currently pending or still 5min+ away) - if ( config.shutdowns > 0 && ( nextAction.deadline == 0 || nextAction.deadline - monoNOW > 300 ) ) { + if ( ! nextAction.force && config.shutdowns > 0 && ( nextAction.deadline == 0 || nextAction.deadline - monoNOW > 300 ) ) { if ( nextAction.deadline != 0 && nextAction.deadline - monoNOW > 300 ) { nextAction.deadline = 0; } @@ -244,7 +251,7 @@ int main( int argc, char **argv ) } } } - if ( nextAction.deadline != 0 ) { + if ( nextAction.deadline != 0 && ( count == 0 || minIdleTime >= config.minIdle || nextAction.force ) ) { // Some action seems pending const int remaining = nextAction.deadline - monoNOW; if ( remaining < -60 ) { @@ -257,8 +264,7 @@ int main( int argc, char **argv ) // Execute! execShutdown( nextAction.action ); nextAction.disarmed = true; - if ( ! _testmode ) { - } + nextAction.force = false; } else if ( remaining < 310 ) { enum Warning w = WARN_REBOOT; if ( nextAction.action == POWEROFF ) { @@ -359,6 +365,7 @@ static struct option long_options[] = { { "screensaver-timeout", required_argument, NULL, 'sst' }, { "dpms-timeout", required_argument, NULL, 'dpms' }, { "grace-period", required_argument, NULL, 'gp' }, + { "min-idle", required_argument, NULL, 'min' }, { "cmd", required_argument, NULL, 'cmd' }, { "send", required_argument, NULL, 'send' }, { "test", no_argument, NULL, 't' }, @@ -398,6 +405,7 @@ static bool parseCmdline( int argc, char **argv ) config.dpmsTimeout = 0; config.gracePeriod = -1; config.shutdownCommand = NULL; + config.minIdle = 0; while ( ( ch = getopt_long( argc, argv, "", long_options, NULL ) ) != -1 ) { switch ( ch ) { case 'pot': @@ -418,6 +426,9 @@ static bool parseCmdline( int argc, char **argv ) case 'gp': config.gracePeriod = atoi( optarg ); break; + case 'min': + config.minIdle = atoi( optarg ); + break; case 'r': case 'p': if ( config.shutdowns < TABMAX ) { @@ -509,6 +520,7 @@ void main_queueAction( enum Shutdown action, int delta ) // Engage nextAction.deadline = monoNOW + delta; nextAction.disarmed = false; + nextAction.force = true; nextAction.action = action; printf( "RPC: Scheduling reboot/poweroff in %d seconds\n", delta ); } -- cgit v1.2.3-55-g7522