Skip to content

Instantly share code, notes, and snippets.

@kev009
Created October 3, 2017 08:51
Show Gist options
  • Save kev009/6a3b281b5612d3735f2c337664fa7aac to your computer and use it in GitHub Desktop.
Save kev009/6a3b281b5612d3735f2c337664fa7aac to your computer and use it in GitHub Desktop.
#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