diff --git a/include/debug.h b/include/debug.h new file mode 100644 index 0000000..b017058 --- /dev/null +++ b/include/debug.h @@ -0,0 +1,11 @@ +#ifndef __DEBUG_H +#define __DEBUG_H + +#ifdef DEBUG +#include +#define TRACE(fmt, ...) fprintf(stderr, "%s:%d:%s\tTRACE\t" fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__) +#else +#define TRACE(fmt, ...) +#endif + +#endif \ No newline at end of file diff --git a/include/process.h b/include/process.h index 86e9a28..c0b94d8 100644 --- a/include/process.h +++ b/include/process.h @@ -28,6 +28,13 @@ typedef struct { gid_t gid; } 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); +// 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 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 1d32886..9f61ac6 100644 --- a/src/main.c +++ b/src/main.c @@ -1,21 +1,32 @@ #include +#include +#include #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) { - process_status_t status = {}; - process_parse_status(getpid(), &status); - - printf("name: %s\n", status.name); - printf("umask: %d\n", status.umask); - printf("state: %d\n", status.state); - 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); + process_status_t* list = NULL; + size_t count = 0; + processes_by_name("dummy_target", &list, &count); + for (size_t i = 0; i < count; i++) + print_process(&list[i]); + + free(list); return 0; } \ No newline at end of file diff --git a/src/process.c b/src/process.c index bad0b6c..68139c9 100644 --- a/src/process.c +++ b/src/process.c @@ -1,9 +1,13 @@ +#define _DEFAULT_SOURCE #include "process.h" +#include "debug.h" #include #include +#include #include #include #include +#include int process_parse_status(pid_t pid, process_status_t* status) { @@ -50,5 +54,61 @@ int process_parse_status(pid_t pid, process_status_t* status) line = strtok_r(NULL, "\n", &lineptr); } + 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; } \ No newline at end of file