[monitoring-plugins] check_procs: general refactoring
Lorenz Kästle
git at monitoring-plugins.org
Sun Jun 29 11:20:11 CEST 2025
Module: monitoring-plugins
Branch: master
Commit: 16c3e2499309af654bcf92a4cc516521122e8d66
Author: Lorenz Kästle <12514511+RincewindsHat at users.noreply.github.com>
Date: Wed Mar 12 14:53:54 2025 +0100
URL: https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=16c3e249
check_procs: general refactoring
---
configure.ac | 2 +-
plugins/check_procs.c | 247 +++++++++++++++++++++++---------------------------
2 files changed, 114 insertions(+), 135 deletions(-)
diff --git a/configure.ac b/configure.ac
index 204fc6e3..c66f9b2f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -796,7 +796,7 @@ elif ps axwo 'stat comm vsz rss user uid pid ppid etime args' 2>/dev/null | \
then
ac_cv_ps_varlist="[procstat,&procuid,&procpid,&procppid,&procvsz,&procrss,&procpcpu,procetime,procprog,&pos]"
ac_cv_ps_command="$PATH_TO_PS axwo 'stat uid pid ppid vsz rss pcpu etime comm args'"
- ac_cv_ps_format="%s %d %d %d %d %d %f %s %s %n"
+ ac_cv_ps_format="%s %u %d %d %d %d %f %s %s %n"
ac_cv_ps_cols=10
AC_MSG_RESULT([$ac_cv_ps_command])
diff --git a/plugins/check_procs.c b/plugins/check_procs.c
index 69b424dc..da2198a7 100644
--- a/plugins/check_procs.c
+++ b/plugins/check_procs.c
@@ -43,6 +43,7 @@ const char *email = "devel at monitoring-plugins.org";
#include "utils.h"
#include "utils_cmd.h"
#include "regex.h"
+#include "states.h"
#include <pwd.h>
#include <errno.h>
@@ -91,7 +92,7 @@ enum metric {
enum metric metric = METRIC_PROCS;
static int verbose = 0;
-static int uid;
+static uid_t uid;
static pid_t ppid;
static int vsz;
static int rss;
@@ -107,62 +108,22 @@ static regex_t re_args;
static char *fmt;
static char *fails;
static char tmp[MAX_INPUT_BUFFER];
-static int kthread_filter = 0;
-static int usepid = 0; /* whether to test for pid or /proc/pid/exe */
+static bool kthread_filter = false;
+static bool usepid = false; /* whether to test for pid or /proc/pid/exe */
static int stat_exe(const pid_t pid, struct stat *buf) {
char *path;
- int ret;
xasprintf(&path, "/proc/%d/exe", pid);
- ret = stat(path, buf);
+ int ret = stat(path, buf);
free(path);
return ret;
}
int main(int argc, char **argv) {
- char *input_buffer;
- char *input_line;
- char *procprog;
-
- pid_t mypid = 0;
- pid_t myppid = 0;
- struct stat statbuf;
- dev_t mydev = 0;
- ino_t myino = 0;
- int procuid = 0;
- pid_t procpid = 0;
- pid_t procppid = 0;
- pid_t kthread_ppid = 0;
- int procvsz = 0;
- int procrss = 0;
- int procseconds = 0;
- float procpcpu = 0;
- char procstat[8];
- char procetime[MAX_INPUT_BUFFER] = {'\0'};
- char *procargs;
-
- const char *zombie = "Z";
-
- int resultsum = 0; /* bitmask of the filter criteria met by a process */
- int found = 0; /* counter for number of lines returned in `ps` output */
- int procs = 0; /* counter for number of processes meeting filter criteria */
- int pos; /* number of spaces before 'args' in `ps` output */
- int cols; /* number of columns in ps output */
- int expected_cols = PS_COLS - 1;
- int warn = 0; /* number of processes in warn state */
- int crit = 0; /* number of processes in crit state */
- int i = 0;
- int result = STATE_UNKNOWN;
- int ret = 0;
- output chld_out, chld_err;
-
setlocale(LC_ALL, "");
+ setlocale(LC_NUMERIC, "POSIX");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- setlocale(LC_NUMERIC, "POSIX");
-
- input_buffer = malloc(MAX_INPUT_BUFFER);
- procprog = malloc(MAX_INPUT_BUFFER);
xasprintf(&metric_name, "PROCS");
metric = METRIC_PROCS;
@@ -175,13 +136,16 @@ int main(int argc, char **argv) {
}
/* find ourself */
- mypid = getpid();
- myppid = getppid();
+ pid_t mypid = getpid();
+ pid_t myppid = getppid();
+ dev_t mydev = 0;
+ ino_t myino = 0;
+ struct stat statbuf;
if (usepid || stat_exe(mypid, &statbuf) == -1) {
/* usepid might have been set by -T */
- usepid = 1;
+ usepid = true;
} else {
- usepid = 0;
+ usepid = false;
mydev = statbuf.st_dev;
myino = statbuf.st_ino;
}
@@ -190,12 +154,15 @@ int main(int argc, char **argv) {
if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
die(STATE_UNKNOWN, _("Cannot catch SIGALRM"));
}
- (void)alarm((unsigned)timeout_interval);
+ (void)alarm(timeout_interval);
if (verbose >= 2) {
printf(_("CMD: %s\n"), PS_COMMAND);
}
+ output chld_out;
+ output chld_err;
+ mp_state_enum result = STATE_UNKNOWN;
if (input_filename == NULL) {
result = cmd_run(PS_COMMAND, &chld_out, &chld_err, 0);
if (chld_err.lines > 0) {
@@ -206,20 +173,43 @@ int main(int argc, char **argv) {
result = cmd_file_read(input_filename, &chld_out, 0);
}
+ int pos; /* number of spaces before 'args' in `ps` output */
+ uid_t procuid = 0;
+ pid_t procpid = 0;
+ pid_t procppid = 0;
+ pid_t kthread_ppid = 0;
+ int warn = 0; /* number of processes in warn state */
+ int crit = 0; /* number of processes in crit state */
+ int procvsz = 0;
+ int procrss = 0;
+ int procseconds = 0;
+ float procpcpu = 0;
+ char procstat[8];
+ char procetime[MAX_INPUT_BUFFER] = {'\0'};
+ int resultsum = 0; /* bitmask of the filter criteria met by a process */
+ int found = 0; /* counter for number of lines returned in `ps` output */
+ int procs = 0; /* counter for number of processes meeting filter criteria */
+ char *input_buffer = malloc(MAX_INPUT_BUFFER);
+ char *procprog = malloc(MAX_INPUT_BUFFER);
+ const int expected_cols = PS_COLS - 1;
+
/* flush first line: j starts at 1 */
for (size_t j = 1; j < chld_out.lines; j++) {
- input_line = chld_out.line[j];
+ char *input_line = chld_out.line[j];
if (verbose >= 3) {
printf("%s", input_line);
}
strcpy(procprog, "");
+ char *procargs;
xasprintf(&procargs, "%s", "");
- cols = sscanf(input_line, PS_FORMAT, PS_VARLIST);
+ /* number of columns in ps output */
+ int cols = sscanf(input_line, PS_FORMAT, PS_VARLIST);
/* Zombie processes do not give a procprog command */
+ const char *zombie = "Z";
if (cols < expected_cols && strstr(procstat, zombie)) {
cols = expected_cols;
}
@@ -240,6 +230,7 @@ int main(int argc, char **argv) {
}
/* Ignore self */
+ int ret = 0;
if ((usepid && mypid == procpid) ||
(((!usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino)) ||
(ret == -1 && errno == ENOENT))) {
@@ -249,7 +240,7 @@ int main(int argc, char **argv) {
continue;
}
/* Ignore parent*/
- else if (myppid == procpid) {
+ if (myppid == procpid) {
if (verbose >= 3) {
printf("not considering - is parent\n");
}
@@ -266,15 +257,13 @@ int main(int argc, char **argv) {
/* Ignore excluded processes by name */
if (options & EXCLUDE_PROGS) {
- int found = 0;
- int i = 0;
-
- for (i = 0; i < (exclude_progs_counter); i++) {
+ bool found = false;
+ for (int i = 0; i < (exclude_progs_counter); i++) {
if (!strcmp(procprog, exclude_progs_arr[i])) {
- found = 1;
+ found = true;
}
}
- if (found == 0) {
+ if (!found) {
resultsum |= EXCLUDE_PROGS;
} else {
if (verbose >= 3) {
@@ -286,7 +275,7 @@ int main(int argc, char **argv) {
/* filter kernel threads (children of KTHREAD_PARENT)*/
/* TODO adapt for other OSes than GNU/Linux
sorry for not doing that, but I've no other OSes to test :-( */
- if (kthread_filter == 1) {
+ if (kthread_filter) {
/* get pid KTHREAD_PARENT */
if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT)) {
kthread_ppid = procpid;
@@ -341,28 +330,29 @@ int main(int argc, char **argv) {
procrss, procpid, procppid, procpcpu, procstat, procetime, procprog, procargs);
}
+ mp_state_enum temporary_result = STATE_OK;
if (metric == METRIC_VSZ) {
- i = get_status((double)procvsz, procs_thresholds);
+ temporary_result = get_status((double)procvsz, procs_thresholds);
} else if (metric == METRIC_RSS) {
- i = get_status((double)procrss, procs_thresholds);
+ temporary_result = get_status((double)procrss, procs_thresholds);
}
/* TODO? float thresholds for --metric=CPU */
else if (metric == METRIC_CPU) {
- i = get_status(procpcpu, procs_thresholds);
+ temporary_result = get_status(procpcpu, procs_thresholds);
} else if (metric == METRIC_ELAPSED) {
- i = get_status((double)procseconds, procs_thresholds);
+ temporary_result = get_status((double)procseconds, procs_thresholds);
}
if (metric != METRIC_PROCS) {
- if (i == STATE_WARNING) {
+ if (temporary_result == STATE_WARNING) {
warn++;
xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog);
- result = max_state(result, i);
+ result = max_state(result, temporary_result);
}
- if (i == STATE_CRITICAL) {
+ if (temporary_result == STATE_CRITICAL) {
crit++;
xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog);
- result = max_state(result, i);
+ result = max_state(result, temporary_result);
}
}
}
@@ -416,20 +406,11 @@ int main(int argc, char **argv) {
}
printf("\n");
- return result;
+ exit(result);
}
/* process command-line arguments */
int process_arguments(int argc, char **argv) {
- int c = 1;
- char *user;
- struct passwd *pw;
- int option = 0;
- int err;
- int cflags = REG_NOSUB | REG_EXTENDED;
- char errbuf[MAX_INPUT_BUFFER];
- char *temp_string;
- int i = 0;
static struct option longopts[] = {{"warning", required_argument, 0, 'w'},
{"critical", required_argument, 0, 'c'},
{"metric", required_argument, 0, 'm'},
@@ -453,20 +434,21 @@ int process_arguments(int argc, char **argv) {
{"exclude-process", required_argument, 0, 'X'},
{0, 0, 0, 0}};
- for (c = 1; c < argc; c++) {
- if (strcmp("-to", argv[c]) == 0) {
- strcpy(argv[c], "-t");
+ for (int index = 1; index < argc; index++) {
+ if (strcmp("-to", argv[index]) == 0) {
+ strcpy(argv[index], "-t");
}
}
- while (1) {
- c = getopt_long(argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", longopts, &option);
+ while (true) {
+ int option = 0;
+ int option_index = getopt_long(argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", longopts, &option);
- if (c == -1 || c == EOF) {
+ if (option_index == -1 || option_index == EOF) {
break;
}
- switch (c) {
+ switch (option_index) {
case '?': /* help */
usage5();
case 'h': /* help */
@@ -504,10 +486,11 @@ int process_arguments(int argc, char **argv) {
xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
options |= STAT;
break;
- case 'u': /* user or user id */
+ case 'u': /* user or user id */ {
+ struct passwd *pw;
if (is_integer(optarg)) {
uid = atoi(optarg);
- pw = getpwuid((uid_t)uid);
+ pw = getpwuid(uid);
/* check to be sure user exists */
if (pw == NULL) {
usage2(_("UID was not found"), optarg);
@@ -521,10 +504,11 @@ int process_arguments(int argc, char **argv) {
/* then get uid */
uid = pw->pw_uid;
}
- user = pw->pw_name;
+
+ char *user = pw->pw_name;
xasprintf(&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""), uid, user);
options |= USER;
- break;
+ } break;
case 'C': /* command */
/* TODO: allow this to be passed in with --metric */
if (prog) {
@@ -542,12 +526,12 @@ int process_arguments(int argc, char **argv) {
exclude_progs = optarg;
}
xasprintf(&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), exclude_progs);
- char *p = strtok(exclude_progs, ",");
+ char *tmp_pointer = strtok(exclude_progs, ",");
- while (p) {
+ while (tmp_pointer) {
exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char *) * ++exclude_progs_counter);
- exclude_progs_arr[exclude_progs_counter - 1] = p;
- p = strtok(NULL, ",");
+ exclude_progs_arr[exclude_progs_counter - 1] = tmp_pointer;
+ tmp_pointer = strtok(NULL, ",");
}
options |= EXCLUDE_PROGS;
@@ -562,23 +546,26 @@ int process_arguments(int argc, char **argv) {
xasprintf(&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args);
options |= ARGS;
break;
- case CHAR_MAX + 1:
- err = regcomp(&re_args, optarg, cflags);
+ case CHAR_MAX + 1: {
+ int cflags = REG_NOSUB | REG_EXTENDED;
+ int err = regcomp(&re_args, optarg, cflags);
if (err != 0) {
+ char errbuf[MAX_INPUT_BUFFER];
regerror(err, &re_args, errbuf, MAX_INPUT_BUFFER);
die(STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf);
}
/* Strip off any | within the regex optarg */
- temp_string = strdup(optarg);
- while (temp_string[i] != '\0') {
- if (temp_string[i] == '|') {
- temp_string[i] = ',';
+ char *temp_string = strdup(optarg);
+ int index = 0;
+ while (temp_string[index] != '\0') {
+ if (temp_string[index] == '|') {
+ temp_string[index] = ',';
}
- i++;
+ index++;
}
xasprintf(&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string);
options |= EREG_ARGS;
- break;
+ } break;
case 'r': /* RSS */
if (sscanf(optarg, "%d%[^0-9]", &rss, tmp) == 1) {
xasprintf(&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss);
@@ -606,29 +593,33 @@ int process_arguments(int argc, char **argv) {
if (strcmp(optarg, "PROCS") == 0) {
metric = METRIC_PROCS;
break;
- } else if (strcmp(optarg, "VSZ") == 0) {
+ }
+ if (strcmp(optarg, "VSZ") == 0) {
metric = METRIC_VSZ;
break;
- } else if (strcmp(optarg, "RSS") == 0) {
+ }
+ if (strcmp(optarg, "RSS") == 0) {
metric = METRIC_RSS;
break;
- } else if (strcmp(optarg, "CPU") == 0) {
+ }
+ if (strcmp(optarg, "CPU") == 0) {
metric = METRIC_CPU;
break;
- } else if (strcmp(optarg, "ELAPSED") == 0) {
+ }
+ if (strcmp(optarg, "ELAPSED") == 0) {
metric = METRIC_ELAPSED;
break;
}
usage4(_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!"));
case 'k': /* linux kernel thread filter */
- kthread_filter = 1;
+ kthread_filter = true;
break;
case 'v': /* command */
verbose++;
break;
case 'T':
- usepid = 1;
+ usepid = true;
break;
case CHAR_MAX + 2:
input_filename = optarg;
@@ -636,15 +627,15 @@ int process_arguments(int argc, char **argv) {
}
}
- c = optind;
- if ((!warning_range) && argv[c]) {
- warning_range = argv[c++];
+ int index = optind;
+ if ((!warning_range) && argv[index]) {
+ warning_range = argv[index++];
}
- if ((!critical_range) && argv[c]) {
- critical_range = argv[c++];
+ if ((!critical_range) && argv[index]) {
+ critical_range = argv[index++];
}
- if (statopts == NULL && argv[c]) {
- xasprintf(&statopts, "%s", argv[c++]);
+ if (statopts == NULL && argv[index]) {
+ xasprintf(&statopts, "%s", argv[index++]);
xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
options |= STAT;
}
@@ -685,25 +676,9 @@ int validate_arguments() {
/* convert the elapsed time to seconds */
int convert_to_seconds(char *etime) {
-
- char *ptr;
- int total;
-
- int hyphcnt;
- int coloncnt;
- int days;
- int hours;
- int minutes;
- int seconds;
-
- hyphcnt = 0;
- coloncnt = 0;
- days = 0;
- hours = 0;
- minutes = 0;
- seconds = 0;
-
- for (ptr = etime; *ptr != '\0'; ptr++) {
+ int hyphcnt = 0;
+ int coloncnt = 0;
+ for (char *ptr = etime; *ptr != '\0'; ptr++) {
if (*ptr == '-') {
hyphcnt++;
@@ -715,6 +690,10 @@ int convert_to_seconds(char *etime) {
}
}
+ int days = 0;
+ int hours = 0;
+ int minutes = 0;
+ int seconds = 0;
if (hyphcnt > 0) {
sscanf(etime, "%d-%d:%d:%d", &days, &hours, &minutes, &seconds);
/* linux 2.6.5/2.6.6 reporting some processes with infinite
@@ -730,7 +709,7 @@ int convert_to_seconds(char *etime) {
}
}
- total = (days * 86400) + (hours * 3600) + (minutes * 60) + seconds;
+ int total = (days * 86400) + (hours * 3600) + (minutes * 60) + seconds;
if (verbose >= 3 && metric == METRIC_ELAPSED) {
printf("seconds: %d\n", total);
More information about the Commits
mailing list