diff --git a/ksysguardd/Linux/ProcessList.c b/ksysguardd/Linux/ProcessList.c --- a/ksysguardd/Linux/ProcessList.c +++ b/ksysguardd/Linux/ProcessList.c @@ -643,26 +643,50 @@ void setPriority( const char* cmd ) { int pid, prio; + char task_dir[64]; + DIR* task = 0; + struct dirent* thread; + int thread_id; /** as: setpriority */ sscanf( cmd, "%*s %d %d", &pid, &prio ); - if ( setpriority( PRIO_PROCESS, pid, prio ) ) { - switch ( errno ) { - case EINVAL: - output( "4\t%d\t%d\n", pid, prio ); - break; - case ESRCH: - output( "3\t%d\t%d\nn", pid, prio ); - break; - case EPERM: - case EACCES: - output( "2\t%d\t%d\n", pid, prio ); - break; - default: /* unknown error */ - output( "1\t%d\t%d\n", pid, prio ); - break; - } - } else + if (snprintf( task_dir, sizeof(task_dir), "/proc/%d/task", pid) >= sizeof(task_dir)) + goto failure; + task = opendir(task_dir); + if (!task) + goto failure; + /* NOTE: this is racy; threads may die or be spawned during our + iteration. Inthat case, we either fail with an error or fail to + set all threads' priorities */ + while (errno = 0, thread = readdir(task)) { + if (thread->d_name[0] == '.') + continue; + if ( setpriority( PRIO_PROCESS, atoi(thread->d_name), prio ) ) + goto failure; + } + if (!errno) { + closedir(task); output( "0\t%d\t%d\n",pid, prio ); + return; + } + + failure: + if (task) closedir(task); + switch ( errno ) { + case EINVAL: + output( "4\t%d\t%d\n", pid, prio ); + break; + case ESRCH: + case ENOENT: + output( "3\t%d\t%d\nn", pid, prio ); + break; + case EPERM: + case EACCES: + output( "2\t%d\t%d\n", pid, prio ); + break; + default: /* unknown error */ + output( "1\t%d\t%d\n", pid, prio ); + break; + } } void ioniceProcess( const char* cmd )