// enumerate all processes bool enumerate_processes(enumerate_processes_callback *callback, int flags) { struct dirent *subdir; DIR *dir; char *path; pid_t pid, ppid; // enumerate through /proc dir = opendir("/proc"); if (dir != NULL) { // first, get a list of all pids while ((subdir = readdir(dir)) != NULL) { if (subdir->d_type == DT_DIR) { pid = string_to_pid(subdir->d_name); if (pid != 0) { ppid = get_parent_pid(pid); pid_list_add(pid, ppid); } } } // create pid tree pid_list_create_tree(); pid_tree_do(pid_tree, callback, 0, flags); pid_list_destroy(); closedir(dir); return true; } else { perror("opendir"); } }
pt_info_t * pt_investigate_kevent (process_tracker_t * pt, struct kevent * ke) { pt_info_t * result; pt_info_t info; if (ke->filter != EVFILT_PROC) goto no_result; if (ke->fflags & NOTE_CHILD) { printf ("new pid %d has %d as parent\n", ke->ident, ke->data); info.event = PT_CHILD; info.pid = ke->ident; info.ppid = ke->data; pid_list_add (pt->pids, pid_new_p (ke->ident)); goto result; } if (ke->fflags & NOTE_EXIT) { pid_list_iterator it; printf ("pid %d exited\n", ke->ident); info.event = PT_EXIT; info.pid = ke->ident; info.ppid = 0; info.flags = ke->data; for (it = pid_list_begin (pt->pids); it != NULL; pid_list_iterator_next (&it)) { if (*it->val == ke->ident) goto found; } goto result; found: free (it->val); pid_list_del (pt->pids, it->val); goto result; } no_result: return 0; result: result = malloc (sizeof (pt_info_t)); *result = info; return result; }
int pt_watch_pid (process_tracker_t * pt, pid_t pid) { int i; struct kevent ke; EV_SET (&ke, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT | NOTE_TRACK, 0, NULL); i = kevent (pt->kq, &ke, 1, NULL, 0, NULL); if (i == -1) fprintf (stderr, "Error: failed to watch PID %d: %s\n", pid, strerror (errno)); else pid_list_add (pt->pids, pid_new_p (pid)); return i == -1 ? 1 : 0; }
int pt_watch_pid (process_tracker_t * pt, pid_t pid) { pid_list_add (pt->pids, pid_new_p (pid)); return 0; }
void unit_register_pid (unit_t * unit, pid_t pid) { pid_t * rpid = s16mem_alloc (sizeof (pid_t)); *rpid = pid; pid_list_add (unit->pids, rpid); }