implement thread enumeration
This commit is contained in:
parent
1f8d733548
commit
0e018fc6c8
3 changed files with 72 additions and 2 deletions
|
|
@ -38,9 +38,12 @@ int process_parse_status(pid_t pid, process_status_t* status);
|
|||
// deallocate list with free later
|
||||
int processes_by_name(const char* name, process_status_t** list, size_t* count);
|
||||
|
||||
// will determine parent process amongst children and set parent pointer to element in list
|
||||
// determine parent process amongst children and set parent pointer to element in list
|
||||
// process list must consist of parent and children processes,
|
||||
// obtained from processes_by_name call. of course parent pointer shouldn't be NULL
|
||||
int determine_parent_process(process_status_t* list, size_t count, process_status_t** parent);
|
||||
|
||||
// get all process threads. for list and count same rules applies as for processes_by_name
|
||||
int process_get_threads(pid_t pid, process_status_t** list, size_t* count);
|
||||
|
||||
#endif
|
||||
19
src/main.c
19
src/main.c
|
|
@ -23,17 +23,34 @@ int main(int argc, char** argv)
|
|||
process_status_t* list = NULL;
|
||||
size_t count = 0;
|
||||
|
||||
// find process
|
||||
processes_by_name("dummy_target", &list, &count);
|
||||
// get real parent
|
||||
process_status_t* parent;
|
||||
if (determine_parent_process(list, count, &parent))
|
||||
{
|
||||
fputs("unable to determine parent process. exiting", stderr);
|
||||
fputs("unable to determine parent process. exiting\n", stderr);
|
||||
free(list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_process(parent);
|
||||
|
||||
// get threads
|
||||
process_status_t* threads = NULL;
|
||||
size_t thread_count = 0;
|
||||
if (process_get_threads(parent->pid, &threads, &thread_count))
|
||||
{
|
||||
fputs("failed to obtain process threads\n", stderr);
|
||||
free(list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
puts("Threads:");
|
||||
for (size_t i = 0; i < thread_count; i++)
|
||||
print_process(&threads[i]);
|
||||
|
||||
free(list);
|
||||
free(threads);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -136,4 +136,54 @@ int determine_parent_process(process_status_t* list, size_t count, process_statu
|
|||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int process_get_threads(pid_t pid, process_status_t** list, size_t* count)
|
||||
{
|
||||
char taskPath[256] = {0};
|
||||
snprintf(taskPath, sizeof(taskPath), "/proc/%d/task", pid);
|
||||
|
||||
DIR* taskDir = opendir(taskPath);
|
||||
if (!taskDir) return 1;
|
||||
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(taskDir)))
|
||||
{
|
||||
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))
|
||||
{
|
||||
// if we can't some threads, we should fail completely
|
||||
// failure is better than incomplete info
|
||||
TRACE("failed to parse %d task status\n", pid);
|
||||
closedir(taskDir);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// add thread to list
|
||||
process_status_t* _list = *list;
|
||||
size_t _count = *count;
|
||||
|
||||
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(taskDir);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// copy thread to list
|
||||
memcpy(&_list[_count - 1], &status, sizeof(process_status_t));
|
||||
|
||||
*list = _list;
|
||||
*count = _count;
|
||||
}
|
||||
|
||||
closedir(taskDir);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue