Created
October 3, 2017 08:51
-
-
Save kev009/6a3b281b5612d3735f2c337664fa7aac to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <regex.h> | |
#include <sys/types.h> | |
#include <sys/sysctl.h> | |
#include <sys/user.h> | |
static char *zbx_regexp(const char *string, const char *pattern, int *len, int flags) | |
{ | |
static char *old_pattern = NULL; | |
static int old_flags; | |
static regex_t re; | |
char *c = NULL; | |
regmatch_t match; | |
if (NULL != len) | |
*len = 0; | |
if (NULL == string) | |
goto out; | |
/* performance optimization: if possible then reuse the last compiled regexp */ | |
if (NULL == old_pattern) | |
goto compile; | |
if (0 != strcmp(old_pattern, pattern) || old_flags != flags) | |
regfree(&re); | |
else | |
goto execute; | |
compile: | |
if (0 == regcomp(&re, pattern, flags)) | |
{ | |
old_pattern = strdup(pattern); | |
old_flags = flags; | |
} | |
else | |
{ | |
free(old_pattern); | |
goto out; | |
} | |
execute: | |
if (0 == regexec(&re, string, (size_t)1, &match, 0)) /* matched */ | |
{ | |
c = (char *)string + match.rm_so; | |
if (NULL != len) | |
*len = match.rm_eo - match.rm_so; | |
} | |
out: | |
return c; | |
} | |
static char *zbx_regexp_match(const char *string, const char *pattern, int *len) | |
{ | |
return zbx_regexp(string, pattern, len, REG_EXTENDED | REG_NEWLINE); | |
} | |
static char *get_commandline(struct kinfo_proc *proc) | |
{ | |
int mib[4], i; | |
size_t sz; | |
static char *args = NULL; | |
static int args_alloc = 128; | |
if (NULL == args) | |
args = malloc(args_alloc); | |
mib[0] = CTL_KERN; | |
mib[1] = KERN_PROC; | |
mib[2] = KERN_PROC_ARGS; | |
mib[3] = proc->ki_pid; | |
retry: | |
sz = (size_t)args_alloc; | |
if (-1 == sysctl(mib, 4, args, &sz, NULL, 0)) | |
{ | |
if (errno == ENOMEM) { | |
args_alloc *= 2; | |
args = realloc(args, args_alloc); | |
goto retry; | |
} | |
return NULL; | |
} | |
for (i = 0; i < (int)(sz - 1); i++) | |
if (args[i] == '\0') | |
args[i] = ' '; | |
if (sz == 0) | |
strlcpy(args, proc->ki_comm, args_alloc); | |
return args; | |
} | |
int main() { | |
char *procname, *proccomm, *args; | |
int count, mib[4], mibs, proc_ok, comm_ok, i; | |
int proccount = 0; | |
size_t sz = 0; | |
struct kinfo_proc *proc = NULL; | |
procname = ""; | |
proccomm = "diskd"; | |
mib[0] = CTL_KERN; | |
mib[1] = KERN_PROC; | |
mib[2] = KERN_PROC_PROC; | |
mib[3] = 0; | |
mibs = 3; | |
if (0 != sysctl(mib, mibs, NULL, &sz, NULL, 0)) | |
abort(); | |
proc = (struct kinfo_proc *) malloc(sz); | |
if (0 != sysctl(mib, mibs, proc, &sz, NULL, 0)) | |
abort(); | |
count = sz / sizeof(struct kinfo_proc); | |
for(i = 0; i < count; i++) { | |
proc_ok = 0; | |
comm_ok = 0; | |
if (NULL == procname || '\0' == *procname || 0 == strcmp(procname, proc[i].ki_comm)) | |
proc_ok = 1; | |
if (NULL != proccomm && '\0' != *proccomm) { | |
if (NULL != (args = get_commandline(&proc[i]))) | |
if (NULL != zbx_regexp_match(args, proccomm, NULL)) | |
comm_ok = 1; | |
} | |
else | |
comm_ok = 1; | |
if (proc_ok && comm_ok) | |
proccount++; | |
} | |
free(proc); | |
printf("procs: %d\n", proccount); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment