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 "../paths.h"
13#include "../proc.h"
14#include "../util.h"
15
16int
17parsecmdline(pid_t pid, char *buf, size_t siz)
18{
19 int fd;
20 char path[PATH_MAX];
21 ssize_t n, i;
22
23 snprintf(path, sizeof(path), ARUU_LINUX_PATH_PROC "/%ld/cmdline", (long)pid);
24 fd = open(path, O_RDONLY);
25 if (fd < 0)
26 return -1;
27 n = read(fd, buf, siz > 0 ? siz - 1 : 0);
28 if (n < 0) {
29 weprintf("read %s:", path);
30 close(fd);
31 return -1;
32 }
33 if (!n) {
34 close(fd);
35 return -1;
36 }
37 buf[n] = '\0';
38 for (i = 0; i < n; i++)
39 if (buf[i] == '\0')
40 buf[i] = ' ';
41 close(fd);
42 return 0;
43}
44
45int
46parsestat(pid_t pid, struct procstat *ps)
47{
48 char path[PATH_MAX];
49 FILE *fp;
50 size_t len;
51
52 snprintf(path, sizeof(path), ARUU_LINUX_PATH_PROC "/%d/stat", pid);
53 if (!(fp = fopen(path, "r")))
54 return -1;
55 fscanf(
56 fp,
57 "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu",
58 &ps->pid,
59 ps->comm,
60 &ps->state,
61 &ps->ppid,
62 &ps->pgrp,
63 &ps->sid,
64 &ps->tty_nr,
65 &ps->tpgid,
66 &ps->flags,
67 &ps->minflt,
68 &ps->cminflt,
69 &ps->majflt,
70 &ps->cmajflt,
71 &ps->utime,
72 &ps->stime
73 );
74 fscanf(
75 fp,
76 "%ld %ld %ld %ld %ld %ld %llu %lu %ld %ld",
77 &ps->cutime,
78 &ps->cstime,
79 &ps->priority,
80 &ps->nice,
81 &ps->num_threads,
82 &ps->itrealvalue,
83 &ps->starttime,
84 &ps->vsize,
85 &ps->rss,
86 &ps->rsslim
87 );
88 /* Filter out '(' and ')' from comm */
89 if ((len = strlen(ps->comm)) > 0)
90 len--;
91 ps->comm[len] = '\0';
92 memmove(ps->comm, ps->comm + 1, len);
93 fclose(fp);
94 return 0;
95}
96
97int
98parsestatus(pid_t pid, struct procstatus *pstatus)
99{
100 char path[PATH_MAX];
101 char buf[BUFSIZ], *off;
102 int fd;
103 ssize_t n;
104
105 snprintf(path, sizeof(path), ARUU_LINUX_PATH_PROC "/%d/status", pid);
106 fd = open(path, O_RDONLY);
107 if (fd < 0)
108 return -1;
109 n = read(fd, buf, sizeof(buf) - 1);
110 if (n < 0)
111 eprintf("%s: read error:", path);
112 if (!n) {
113 close(fd);
114 return -1;
115 }
116 buf[n] = '\0';
117 close(fd);
118 off = strstr(buf, "Uid:");
119 if (!off)
120 return -1;
121 sscanf(off, "Uid: %u %u", &pstatus->uid, &pstatus->euid);
122 off = strstr(buf, "Gid:");
123 if (!off)
124 return -1;
125 sscanf(off, "Gid: %u %u", &pstatus->gid, &pstatus->egid);
126 return 0;
127}
128
129int
130pidfile(const char *file)
131{
132 char *end;
133
134 errno = 0;
135 strtol(file, &end, 10);
136 if (*end != '\0')
137 return 0;
138 if (errno != 0)
139 return 0;
140 return 1;
141}