summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2019-10-18 16:48:22 +0200
committerSimon Rettberg2019-10-18 16:48:22 +0200
commit43028a40d5d68bb3bf5e6e0dc7a7a5888e64a706 (patch)
tree0b6104a310115e511cbb92a529a848735ca36fc9
parentFix fd leak (diff)
downloadidle-daemon-43028a40d5d68bb3bf5e6e0dc7a7a5888e64a706.tar.gz
idle-daemon-43028a40d5d68bb3bf5e6e0dc7a7a5888e64a706.tar.xz
idle-daemon-43028a40d5d68bb3bf5e6e0dc7a7a5888e64a706.zip
Add feature to clean up user processes after logout
-rw-r--r--src/main.c36
-rw-r--r--src/userlist.c11
-rw-r--r--src/userlist.h2
3 files changed, 39 insertions, 10 deletions
diff --git a/src/main.c b/src/main.c
index 9ca1da9..68ae274 100644
--- a/src/main.c
+++ b/src/main.c
@@ -52,6 +52,7 @@ static struct {
int dpmsTimeout;
int gracePeriod;
int minIdle;
+ bool killUserProcesses;
} config;
static time_t combineTime( const time_t now, const struct time * time );
@@ -62,6 +63,8 @@ static bool parseCmdline( int argc, char **argv );
static void execShutdown( enum Shutdown action );
+static void userLoggedOut(struct user* usr);
+
int main( int argc, char **argv )
{
int idx;
@@ -80,7 +83,7 @@ int main( int argc, char **argv )
startWall = time( NULL );
startMono = now();
// Calculate shortest possible sleep time without delaying any timeout related actions
- int defaultSleep = 900;
+ int defaultSleep = 120;
if ( config.logoutTimeout > 0 && config.logoutTimeout < defaultSleep ) {
defaultSleep = config.logoutTimeout;
}
@@ -100,8 +103,13 @@ int main( int argc, char **argv )
userCount = count;
for ( idx = 0; idx < count; ++idx ) {
struct user * const usr = &users[idx];
- if ( !usr->mark ) {
- fprintf( stderr, "This will never happen \\o/\n" );
+ if ( !usr->online ) {
+ if ( !usr->lastOnline ) {
+ fprintf( stderr, "This will never happen \\o/\n" );
+ continue;
+ }
+ // User was logged in, but isn't anymore
+ userLoggedOut(usr);
continue;
}
const time_t NOW = time( NULL );
@@ -384,6 +392,7 @@ static struct option long_options[] = {
{ "min-idle", required_argument, NULL, 'min' },
{ "cmd", required_argument, NULL, 'cmd' },
{ "send", required_argument, NULL, 'send' },
+ { "kill-user-processes", no_argument, NULL, 'kill' },
{ "test", no_argument, NULL, 't' },
{ NULL, 0, NULL, 0 }
};
@@ -422,6 +431,7 @@ static bool parseCmdline( int argc, char **argv )
config.gracePeriod = -1;
config.shutdownCommand = NULL;
config.minIdle = 0;
+ config.killUserProcesses = false;
while ( ( ch = getopt_long( argc, argv, "", long_options, NULL ) ) != -1 ) {
switch ( ch ) {
case 'pot':
@@ -466,6 +476,10 @@ static bool parseCmdline( int argc, char **argv )
break;
case 'send':
exit( !rpc_send( optarg ) );
+ break;
+ case 'kill':
+ config.killUserProcesses = true;
+ break;
default:
fprintf( stderr, "Unhandled command line option %d, aborting\n", ch );
return false;
@@ -518,7 +532,7 @@ void main_getStatus( const char **nextString, time_t *deadline )
struct user* main_getUser( const char *terminal )
{
- for ( int i = 0; i < USERS && users[i].mark; ++i ) {
+ for ( int i = 0; i < userCount; ++i ) {
if ( strcmp( users[i].device, terminal ) == 0
|| strcmp( users[i].display, terminal ) == 0 ) {
return &users[i];
@@ -565,4 +579,18 @@ void main_warnAll( const char *message )
}
}
+static void userLoggedOut(struct user* usr)
+{
+ if ( !config.killUserProcesses )
+ return;
+ for ( int i = 0; i < userCount; ++i ) {
+ if (users[i].online && strcmp(users[i].user, usr->user) == 0)
+ return; // Still an active session
+ }
+ struct passwd *u = getpwnam( usr->user );
+ if ( u == NULL || u->pw_uid < 1000 )
+ return; // Ignore system users
+ printf( "Killing remaining processes of %s\n", usr->user );
+ run( true, "pkill", "-u", usr->user, (char*)NULL );
+}
diff --git a/src/userlist.c b/src/userlist.c
index fffe772..d4dde86 100644
--- a/src/userlist.c
+++ b/src/userlist.c
@@ -52,7 +52,8 @@ int getUserList( struct user *outbuf, int size )
if ( outbuf[i].user[0] != '\0' ) {
deadzone = i + 1;
}
- outbuf[i].mark = false;
+ outbuf[i].lastOnline = outbuf[i].online;
+ outbuf[i].online = false;
}
struct utmp buffer[100];
ssize_t len = read( fh, buffer, sizeof(buffer) );
@@ -114,7 +115,7 @@ int getUserList( struct user *outbuf, int size )
getSessionData( &outbuf[use] );
outbuf[use].loginctlFails++;
}
- outbuf[use].mark = true;
+ outbuf[use].online = true;
// Reset offset if timestamp changed
// but ONLY if this isn't a known X session
if ( outbuf[use].display[0] == '\0' ) {
@@ -128,11 +129,11 @@ int getUserList( struct user *outbuf, int size )
close( fh );
// Compact
for ( int i = 0; i < deadzone; ++i ) {
- if ( outbuf[i].mark )
- continue; // In use
+ if ( outbuf[i].online || outbuf[i].lastOnline )
+ continue; // In use, or just finished
do {
deadzone--;
- if ( outbuf[deadzone].mark ) {
+ if ( outbuf[deadzone].online || outbuf[deadzone].lastOnline ) {
outbuf[i] = outbuf[deadzone];
outbuf[deadzone].user[0] = '\0';
break;
diff --git a/src/userlist.h b/src/userlist.h
index 189b0c2..f9ae458 100644
--- a/src/userlist.h
+++ b/src/userlist.h
@@ -19,7 +19,7 @@ struct user {
int lastActivityOffset;
int lockTimeOffset;
int loginctlFails;
- bool mark;
+ bool online, lastOnline;
bool isLocked;
char user[STRLEN];
char device[STRLEN];