int main (int argc, char *argv[]) { int i; int time; char *args[ARG_MAX+1]; if (argc != 4) { usage(); if (argc == 2 && strcmp(argv[1], "-h") == 0) { exit(0); } else { exit(1); } } time = convert_to_seconds(argv[1], argv[2]); convert_to_argument_list(args, argv[3]); cpid = fork(); if (cpid == 0) { execvp(args[0], args); // if execvp() returns, then something failed: fprintf(stderr, "error: unable to exec the command\n"); exit(1); } else if (cpid > 0) { signal(SIGINT, sighandler); signal(SIGTERM, sighandler); sleep(time); kill_child(); } else { fprintf(stderr, "error: unable to fork\n"); exit(1); } return 0; }
int main (int argc, char **argv) { char *input_buffer; char *input_line; char *procprog; pid_t mypid = 0; int procuid = 0; pid_t procpid = 0; pid_t procppid = 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, j = 0; int result = STATE_UNKNOWN; output chld_out, chld_err; setlocale (LC_ALL, ""); 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; /* Parse extra opts if any */ argv=np_extra_opts (&argc, argv, progname); if (process_arguments (argc, argv) == ERROR) usage4 (_("Could not parse arguments")); /* get our pid */ mypid = getpid(); /* Set signal handling and alarm timeout */ if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { die (STATE_UNKNOWN, _("Cannot catch SIGALRM")); } (void) alarm ((unsigned) timeout_interval); if (verbose >= 2) printf (_("CMD: %s\n"), PS_COMMAND); if (input_filename == NULL) { result = cmd_run( PS_COMMAND, &chld_out, &chld_err, 0); if (chld_err.lines > 0) { printf ("%s: %s", _("System call sent warnings to stderr"), chld_err.line[0]); exit(STATE_WARNING); } } else { result = cmd_file_read( input_filename, &chld_out, 0); } /* flush first line: j starts at 1 */ for (j = 1; j < chld_out.lines; j++) { input_line = chld_out.line[j]; if (verbose >= 3) printf ("%s", input_line); strcpy (procprog, ""); xasprintf (&procargs, "%s", ""); cols = sscanf (input_line, PS_FORMAT, PS_VARLIST); /* Zombie processes do not give a procprog command */ if ( cols < expected_cols && strstr(procstat, zombie) ) { cols = expected_cols; } if ( cols >= expected_cols ) { resultsum = 0; xasprintf (&procargs, "%s", input_line + pos); strip (procargs); /* Some ps return full pathname for command. This removes path */ strcpy(procprog, base_name(procprog)); /* we need to convert the elapsed time to seconds */ procseconds = convert_to_seconds(procetime); if (verbose >= 3) printf ("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", procs, procuid, procvsz, procrss, procpid, procppid, procpcpu, procstat, procetime, procprog, procargs); /* Ignore self */ if (mypid == procpid) continue; if ((options & STAT) && (strstr (statopts, procstat))) resultsum |= STAT; if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL)) resultsum |= ARGS; if ((options & EREG_ARGS) && procargs && (regexec(&re_args, procargs, (size_t) 0, NULL, 0) == 0)) resultsum |= EREG_ARGS; if ((options & PROG) && procprog && (strcmp (prog, procprog) == 0)) resultsum |= PROG; if ((options & PPID) && (procppid == ppid)) resultsum |= PPID; if ((options & USER) && (procuid == uid)) resultsum |= USER; if ((options & VSZ) && (procvsz >= vsz)) resultsum |= VSZ; if ((options & RSS) && (procrss >= rss)) resultsum |= RSS; if ((options & PCPU) && (procpcpu >= pcpu)) resultsum |= PCPU; found++; /* Next line if filters not matched */ if (!(options == resultsum || options == ALL)) continue; procs++; if (verbose >= 2) { printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", procuid, procvsz, procrss, procpid, procppid, procpcpu, procstat, procetime, procprog, procargs); } if (metric == METRIC_VSZ) i = get_status ((double)procvsz, procs_thresholds); else if (metric == METRIC_RSS) i = get_status ((double)procrss, procs_thresholds); /* TODO? float thresholds for --metric=CPU */ else if (metric == METRIC_CPU) i = get_status (procpcpu, procs_thresholds); else if (metric == METRIC_ELAPSED) i = get_status ((double)procseconds, procs_thresholds); if (metric != METRIC_PROCS) { if (i == STATE_WARNING) { warn++; xasprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog); result = max_state (result, i); } if (i == STATE_CRITICAL) { crit++; xasprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog); result = max_state (result, i); } } } /* This should not happen */ else if (verbose) { printf(_("Not parseable: %s"), input_buffer); } } if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */ printf (_("Unable to read output\n")); return STATE_UNKNOWN; } if ( result == STATE_UNKNOWN ) result = STATE_OK; /* Needed if procs found, but none match filter */ if ( metric == METRIC_PROCS ) { result = max_state (result, get_status ((double)procs, procs_thresholds) ); } if ( result == STATE_OK ) { printf ("%s %s: ", metric_name, _("OK")); } else if (result == STATE_WARNING) { printf ("%s %s: ", metric_name, _("WARNING")); if ( metric != METRIC_PROCS ) { printf (_("%d warn out of "), warn); } } else if (result == STATE_CRITICAL) { printf ("%s %s: ", metric_name, _("CRITICAL")); if (metric != METRIC_PROCS) { printf (_("%d crit, %d warn out of "), crit, warn); } } printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs); if (strcmp(fmt,"") != 0) { printf (_(" with %s"), fmt); } if ( verbose >= 1 && strcmp(fails,"") ) printf (" [%s]", fails); if (metric == METRIC_PROCS) printf (" | procs=%d;%s;%s;0;", procs, warning_range ? warning_range : "", critical_range ? critical_range : ""); else printf (" | procs=%d;;;0; procs_warn=%d;;;0; procs_crit=%d;;;0;", procs, warn, crit); printf ("\n"); return result; }