proc.c - ubase - suckless linux base utils | |
git clone git://git.suckless.org/ubase | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
proc.c (2391B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include <sys/stat.h> | |
3 | |
4 #include <errno.h> | |
5 #include <fcntl.h> | |
6 #include <limits.h> | |
7 #include <stdio.h> | |
8 #include <stdlib.h> | |
9 #include <string.h> | |
10 #include <unistd.h> | |
11 | |
12 #include "../proc.h" | |
13 #include "../util.h" | |
14 | |
15 int | |
16 parsecmdline(pid_t pid, char *buf, size_t siz) | |
17 { | |
18 int fd; | |
19 char path[PATH_MAX]; | |
20 ssize_t n, i; | |
21 | |
22 snprintf(path, sizeof(path), "/proc/%ld/cmdline", (long)pid); | |
23 fd = open(path, O_RDONLY); | |
24 if (fd < 0) | |
25 return -1; | |
26 n = read(fd, buf, siz > 0 ? siz - 1 : 0); | |
27 if (n < 0) { | |
28 weprintf("read %s:", path); | |
29 close(fd); | |
30 return -1; | |
31 } | |
32 if (!n) { | |
33 close(fd); | |
34 return -1; | |
35 } | |
36 buf[n] = '\0'; | |
37 for (i = 0; i < n; i++) | |
38 if (buf[i] == '\0') | |
39 buf[i] = ' '; | |
40 close(fd); | |
41 return 0; | |
42 } | |
43 | |
44 int | |
45 parsestat(pid_t pid, struct procstat *ps) | |
46 { | |
47 char path[PATH_MAX]; | |
48 FILE *fp; | |
49 size_t len; | |
50 | |
51 snprintf(path, sizeof(path), "/proc/%d/stat", pid); | |
52 if (!(fp = fopen(path, "r"))) | |
53 return -1; | |
54 fscanf(fp, "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu", | |
55 &ps->pid, ps->comm, | |
56 &ps->state, &ps->ppid, &ps->pgrp, | |
57 &ps->sid, &ps->tty_nr, &ps->tpgid, &ps->flags, | |
58 &ps->minflt, &ps->cminflt, &ps->majflt, &ps->cmajflt, | |
59 &ps->utime, &ps->stime); | |
60 fscanf(fp, "%ld %ld %ld %ld %ld %ld %llu %lu %ld %ld", | |
61 &ps->cutime, &ps->cstime, &ps->priority, &ps->nice, | |
62 &ps->num_threads, &ps->itrealvalue, &ps->starttime, | |
63 &ps->vsize, &ps->rss, &ps->rsslim); | |
64 /* Filter out '(' and ')' from comm */ | |
65 if ((len = strlen(ps->comm)) > 0) | |
66 len--; | |
67 ps->comm[len] = '\0'; | |
68 memmove(ps->comm, ps->comm + 1, len); | |
69 fclose(fp); | |
70 return 0; | |
71 } | |
72 | |
73 int | |
74 parsestatus(pid_t pid, struct procstatus *pstatus) | |
75 { | |
76 char path[PATH_MAX]; | |
77 char buf[BUFSIZ], *off; | |
78 int fd; | |
79 ssize_t n; | |
80 | |
81 snprintf(path, sizeof(path), "/proc/%d/status", pid); | |
82 fd = open(path, O_RDONLY); | |
83 if (fd < 0) | |
84 return -1; | |
85 n = read(fd, buf, sizeof(buf) - 1); | |
86 if (n < 0) | |
87 eprintf("%s: read error:", path); | |
88 if (!n) { | |
89 close(fd); | |
90 return -1; | |
91 } | |
92 buf[n] = '\0'; | |
93 close(fd); | |
94 off = strstr(buf, "Uid:"); | |
95 if (!off) | |
96 return -1; | |
97 sscanf(off, "Uid: %u %u", &pstatus->uid, &pstatus->euid); | |
98 off = strstr(buf, "Gid:"); | |
99 if (!off) | |
100 return -1; | |
101 sscanf(off, "Gid: %u %u", &pstatus->gid, &pstatus->egid); | |
102 return 0; | |
103 } | |
104 | |
105 int | |
106 pidfile(const char *file) | |
107 { | |
108 char *end; | |
109 | |
110 errno = 0; | |
111 strtol(file, &end, 10); | |
112 if (*end != '\0') | |
113 return 0; | |
114 if (errno != 0) | |
115 return 0; | |
116 return 1; | |
117 } |