From e18981ec0af8c72b23b88fa1f592d689097959e7 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Sun, 24 Apr 2022 00:00:00 -0500 Subject: [PATCH] top: added provision for autogroup nice (AGNI) changes When autogroups are active programs such as renice and nice are basically useless because the nice value will only affect the target task priority relative to other processes in the same autogroup. So to accomplish what we thought of as renice, /proc//autogroup must be changed. Altering a single member in an autogroup will also affect every other member of that same autogroup. Since top's renice provision ('r') suffers constraints like those of the stand alone nice/renice programs, we will now provide a means to manipulate that nice value found within some process' /proc//autogroup file. [ to alter this file for other user's tasks requires ] [ root privileges, as does setting a negative value. ] [ however, unlike that 'r' command, this new command ] [ allows raising *and* lowering all positive values. ] Reference(s): . Aug 2021, autogroups added to librady commit 631e5d91f3c34374a095b8351235627545617de7 . Aug 2021, autogroups added to top commit b789b46f84da590a39afd8d74c76c2f5e5436d40 Signed-off-by: Jim Warner --- top/top.c | 28 +++++++++++++++++++++++++++- top/top.h | 4 +++- top/top_nls.c | 6 +++++- top/top_nls.h | 1 + 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/top/top.c b/top/top.c index b63c1558..e321bc59 100644 --- a/top/top.c +++ b/top/top.c @@ -5223,6 +5223,32 @@ static void keys_global (int ch) { Rc.tics_scaled = 0; #endif break; + case kbd_CtrlR: + if (Secure_mode) + show_msg(N_txt(NOT_onsecure_txt)); + else { + int def = PID_VAL(EU_PID, s_int, w->ppt[w->begtask]), + pid = get_int(fmtmk(N_fmt(GET_pid2nice_fmt), def)); + if (pid > GET_NUM_ESC) { + int val, fd; + if (pid == GET_NUM_NOT) pid = def; + val = get_int(fmtmk(N_fmt(AGNI_valueof_fmt), pid)); + if (val > GET_NUM_NOT) { + if (val < -20 || val > +19) + show_msg(N_txt(AGNI_invalid_txt)); + else if (0 > (fd = open(fmtmk("/proc/%d/autogroup", pid), O_WRONLY))) + show_msg(fmtmk(N_fmt(AGNI_notopen_fmt), strerror(errno))); + else { + char buf[TNYBUFSIZ]; + snprintf(buf, sizeof(buf), "%d", val); + if (0 >= write(fd, buf, strlen(buf))) + show_msg(fmtmk(N_fmt(AGNI_nowrite_fmt), strerror(errno))); + close(fd); + } + } + } + } + break; case kbd_ENTER: // these two have the effect of waking us case kbd_SPACE: // from 'pselect', refreshing the display break; // and updating any hot-plugged resources @@ -6063,7 +6089,7 @@ static void do_key (int ch) { { keys_global, { '?', 'B', 'd', 'E', 'e', 'f', 'g', 'H', 'h' , 'I', 'k', 'r', 's', 'X', 'Y', 'Z', '0' - , kbd_CtrlE, kbd_ENTER, kbd_SPACE, '\0' } }, + , kbd_CtrlE, kbd_CtrlR, kbd_ENTER, kbd_SPACE, '\0' } }, { keys_summary, { '!', '1', '2', '3', '4', 'C', 'l', 'm', 't', '\0' } }, { keys_task, diff --git a/top/top.h b/top/top.h index 5b9436f4..06271700 100644 --- a/top/top.h +++ b/top/top.h @@ -130,6 +130,7 @@ char *strcasestr(const char *haystack, const char *needle); /* the above might seem pretty stingy, until you consider that with every field displayed the column header would be approximately 250 bytes -- so SCREENMAX provides for all fields plus a 250+ byte command line */ +#define TNYBUFSIZ 16 #define CAPBUFSIZ 32 #define CLRBUFSIZ 64 #define PFLAGSSIZ 128 @@ -169,8 +170,9 @@ char *strcasestr(const char *haystack, const char *needle); #define kbd_BKSP 137 #define kbd_INS 138 #define kbd_DEL 139 -#define kbd_CtrlO '\017' #define kbd_CtrlE '\005' +#define kbd_CtrlO '\017' +#define kbd_CtrlR '\022' /* Special value in Pseudo_row to force an additional procs refresh -- used at startup and for task/thread mode transitions */ diff --git a/top/top_nls.c b/top/top_nls.c index bdf8ad1f..23a83851 100644 --- a/top/top_nls.c +++ b/top/top_nls.c @@ -584,6 +584,10 @@ static void build_norm_nlstab (void) { Norm_nlstab[X_SEMAPHORES_fmt] = _("failed sem_init() at %d: %s"); Norm_nlstab[X_THREADINGS_fmt] = _("failed pthread_create() at %d: %s"); Norm_nlstab[X_RESTRICTED_txt] = _("sorry, restricted namespace with reduced functionality"); + Norm_nlstab[AGNI_valueof_fmt] = _("set pid %d AGNI value to"); + Norm_nlstab[AGNI_invalid_txt] = _("valid AGNI range is -20 to +19"); + Norm_nlstab[AGNI_notopen_fmt] = _("autogroup open failed, %s"); + Norm_nlstab[AGNI_nowrite_fmt] = _("autogroup write failed, %s"); } @@ -718,7 +722,7 @@ static void build_uniq_nlstab (void) { . also imbedded in the translatable text (along with escape seqs) . should never themselves be translated. */ Uniq_nlstab[KEYS_helpext_fmt] = _("" - " k,r Manipulate tasks: '~1k~2' kill; '~1r~2' renice\n" + " k,r,^R, Tasks: '~1k~2' kill; '~1r~2' renice; ~1Ctrl~2+'~1R~2' renice autogroup\n" " d or s Set update interval\n"); /* Translation Hint: diff --git a/top/top_nls.h b/top/top_nls.h index a9c14533..8ae505f1 100644 --- a/top/top_nls.h +++ b/top/top_nls.h @@ -60,6 +60,7 @@ extern const char *Uniq_nlstab[]; * from any text also containiing c-format specifiers. */ enum norm_nls { + AGNI_invalid_txt, AGNI_notopen_fmt, AGNI_nowrite_fmt, AGNI_valueof_fmt, AMT_exxabyte_txt, AMT_gigabyte_txt, AMT_kilobyte_txt, AMT_megabyte_txt, AMT_petabyte_txt, AMT_terabyte_txt, BAD_delayint_fmt, BAD_integers_txt, BAD_max_task_txt, BAD_memscale_fmt, BAD_mon_pids_fmt, BAD_niterate_fmt,