implement process enumeration by executable name
This commit is contained in:
parent
924a3fafe5
commit
8650359177
4 changed files with 102 additions and 13 deletions
11
include/debug.h
Normal file
11
include/debug.h
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef __DEBUG_H
|
||||||
|
#define __DEBUG_H
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#define TRACE(fmt, ...) fprintf(stderr, "%s:%d:%s\tTRACE\t" fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define TRACE(fmt, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -28,6 +28,13 @@ typedef struct {
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
} process_status_t;
|
} process_status_t;
|
||||||
|
|
||||||
|
// parse process status from procfs. returns 0 no errors and 1 on any kind of error
|
||||||
|
// error information obtain from errno
|
||||||
int process_parse_status(pid_t pid, process_status_t* status);
|
int process_parse_status(pid_t pid, process_status_t* status);
|
||||||
|
|
||||||
|
// find any process that matches name, case insensitive.
|
||||||
|
// list pointer must point to NULL-initialized pointer, and count pointer must pount to initialized 0
|
||||||
|
// will skip any process which status couldn't be parsed
|
||||||
|
int processes_by_name(const char* name, process_status_t** list, size_t* count);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
35
src/main.c
35
src/main.c
|
|
@ -1,21 +1,32 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
|
|
||||||
|
void print_process(process_status_t* proc)
|
||||||
|
{
|
||||||
|
puts("Process:");
|
||||||
|
printf("name: %s\n", proc->name);
|
||||||
|
printf("umask: %d\n", proc->umask);
|
||||||
|
printf("state: %d\n", proc->state);
|
||||||
|
printf("tgid: %d\n", proc->tgid);
|
||||||
|
printf("ngid: %d\n", proc->ngid);
|
||||||
|
printf("pid: %d\n", proc->pid);
|
||||||
|
printf("ppid: %d\n", proc->ppid);
|
||||||
|
printf("tracer_pid: %d\n", proc->tracer_pid);
|
||||||
|
printf("uid: %d\n", proc->uid);
|
||||||
|
printf("gid: %d\n", proc->gid);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
process_status_t status = {};
|
process_status_t* list = NULL;
|
||||||
process_parse_status(getpid(), &status);
|
size_t count = 0;
|
||||||
|
|
||||||
printf("name: %s\n", status.name);
|
processes_by_name("dummy_target", &list, &count);
|
||||||
printf("umask: %d\n", status.umask);
|
for (size_t i = 0; i < count; i++)
|
||||||
printf("state: %d\n", status.state);
|
print_process(&list[i]);
|
||||||
printf("tgid: %d\n", status.tgid);
|
|
||||||
printf("ngid: %d\n", status.ngid);
|
|
||||||
printf("pid: %d\n", status.pid);
|
|
||||||
printf("ppid: %d\n", status.ppid);
|
|
||||||
printf("tracer_pid: %d\n", status.tracer_pid);
|
|
||||||
printf("uid: %d\n", status.uid);
|
|
||||||
printf("gid: %d\n", status.gid);
|
|
||||||
|
|
||||||
|
free(list);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
|
#define _DEFAULT_SOURCE
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
|
#include "debug.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
int process_parse_status(pid_t pid, process_status_t* status)
|
int process_parse_status(pid_t pid, process_status_t* status)
|
||||||
{
|
{
|
||||||
|
|
@ -52,3 +56,59 @@ int process_parse_status(pid_t pid, process_status_t* status)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int is_numeric(const char* str)
|
||||||
|
{
|
||||||
|
for (const char* p = str; *p; p++)
|
||||||
|
if (!isdigit(*p)) return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int processes_by_name(const char* name, process_status_t** list, size_t* count)
|
||||||
|
{
|
||||||
|
DIR* proc = opendir("/proc");
|
||||||
|
if (!proc) return 1;
|
||||||
|
|
||||||
|
struct dirent* entry;
|
||||||
|
while ((entry = readdir(proc)))
|
||||||
|
{
|
||||||
|
if (entry->d_type != DT_DIR) continue;
|
||||||
|
if (!is_numeric(entry->d_name)) continue;
|
||||||
|
|
||||||
|
pid_t pid = strtod(entry->d_name, NULL);
|
||||||
|
process_status_t status = {};
|
||||||
|
if (process_parse_status(pid, &status))
|
||||||
|
{
|
||||||
|
TRACE("process parse status failed for %d\n", pid);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcasecmp(status.name, name))
|
||||||
|
{
|
||||||
|
// we have match! lets add it to list
|
||||||
|
size_t _count = *count;
|
||||||
|
process_status_t* _list = *list;
|
||||||
|
|
||||||
|
if (_count) _list = (process_status_t*)realloc(_list, ++_count * sizeof(process_status_t));
|
||||||
|
else _list = (process_status_t*)malloc(++_count * sizeof(process_status_t));
|
||||||
|
|
||||||
|
if (!_list)
|
||||||
|
{
|
||||||
|
TRACE("out of memory for process status!\n");
|
||||||
|
closedir(proc);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy process status to list
|
||||||
|
memcpy(&_list[_count - 1], &status, sizeof(process_status_t));
|
||||||
|
|
||||||
|
// update pointers
|
||||||
|
*list = _list;
|
||||||
|
*count = _count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(proc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue