implement process enumeration by executable name

This commit is contained in:
mykola2312 2024-07-20 22:05:29 +03:00
parent 924a3fafe5
commit 8650359177
4 changed files with 102 additions and 13 deletions

11
include/debug.h Normal file
View 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

View file

@ -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

View file

@ -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;
} }

View file

@ -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;
}