diff options
Diffstat (limited to 'src/api.c')
-rw-r--r-- | src/api.c | 55 |
1 files changed, 55 insertions, 0 deletions
@@ -2477,3 +2477,58 @@ int cgroup_get_task_begin(char *cgroup, char *controller, void **handle, return ret; } + +int cgroup_get_procdata_from_status(pid_t pid, uid_t *euid, gid_t *egid, + char *procname, size_t size_procname) +{ + FILE *f; + char path[FILENAME_MAX]; + char buf[4092]; + uid_t ruid, suid, fsuid; + gid_t rgid, sgid, fsgid; + bool find_euid = false; + bool find_egid = false; + bool find_procname = false; + + if (euid) + find_euid = true; + if (egid) + find_egid = true; + if (procname) + find_procname = true; + + sprintf(path, "/proc/%d/status", pid); + f = fopen(path, "r"); + if (!f) + return 1; + + memset(buf, '\0', sizeof(buf)); + while (fgets(buf, sizeof(buf), f)) { + if (!strncmp(buf, "Uid:", 4) && find_euid) { + sscanf((buf + 5), "%d%d%d%d", &ruid, euid, + &suid, &fsuid); + cgroup_dbg("Scanned proc values are %d %d %d %d\n", + ruid, *euid, suid, fsuid); + find_euid = false; + } else if (!strncmp(buf, "Gid:", 4) && find_egid) { + sscanf((buf + 5), "%d%d%d%d", &rgid, egid, + &sgid, &fsgid); + cgroup_dbg("Scanned proc values are %d %d %d %d\n", + rgid, *egid, sgid, fsgid); + find_egid = false; + } else if (!strncmp(buf, "Name:", 5) && find_procname && + (strlen(buf + 6) < size_procname)) { + sscanf((buf + 6), "%s", procname); + find_procname = false; + } + if (!find_euid && !find_egid && !find_procname) { + fclose(f); + return 0; + } + memset(buf, '\0', sizeof(buf)); + } + /* failed to find some process data. */ + fclose(f); + return 1; +} + |