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;
|
||||
} 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
|
||||
35
src/main.c
35
src/main.c
|
|
@ -1,21 +1,32 @@
|
|||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.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)
|
||||
{
|
||||
process_status_t status = {};
|
||||
process_parse_status(getpid(), &status);
|
||||
process_status_t* list = NULL;
|
||||
size_t count = 0;
|
||||
|
||||
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);
|
||||
processes_by_name("dummy_target", &list, &count);
|
||||
for (size_t i = 0; i < count; i++)
|
||||
print_process(&list[i]);
|
||||
|
||||
free(list);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,9 +1,13 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
#include "process.h"
|
||||
#include "debug.h"
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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