GCC Code Coverage Report


Directory: src/gate/
File: src/gate/platform/linux/procfs.h
Date: 2025-12-12 23:40:09
Exec Total Coverage
Lines: 54 60 90.0%
Functions: 6 6 100.0%
Branches: 12 24 50.0%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #ifndef GATE_PLATFORM_LINUX_PROCFS_H_INCLUDED
30 #define GATE_PLATFORM_LINUX_PROCFS_H_INCLUDED
31
32 #include "gate/gatetypes.h"
33 #include "gate/strings.h"
34
35 #ifdef GATE_SYS_LINUX
36
37 #include <stdio.h>
38 #include <dirent.h>
39 #include <unistd.h>
40 #include <sys/sysinfo.h>
41 #include <sys/stat.h>
42
43 typedef struct gate_procfs_proc_stat
44 {
45 int pid;
46 char comm[256];
47 char state;
48 int ppid;
49 int pgrp;
50 int session;
51 int tty_nr;
52 int tpgid;
53 unsigned flags;
54 unsigned long minflt;
55 unsigned long cminflt;
56 unsigned long majflt;
57 unsigned long cmajflt;
58 unsigned long utime;
59 unsigned long stime;
60 long long cutime;
61 long long cstime;
62 long long priority;
63 long long nice;
64 long long num_threads;
65 long long itrealvalue;
66 unsigned long long starttime;
67 unsigned long vsize;
68 long rss;
69 unsigned long rsslim;
70 unsigned long startcode;
71 unsigned long endcode;
72 unsigned long startstack;
73 unsigned long kstkesp;
74 unsigned long kstkeip;
75 unsigned long signal;
76 unsigned long blocked;
77 unsigned long sigignore;
78 unsigned long sigcatch;
79 unsigned long wchan;
80 unsigned long nswap;
81 unsigned long cnswap;
82 int exit_signal;
83 int processor;
84 unsigned rt_priority;
85 unsigned policy;
86 unsigned long long delayacct_blkio_ticks;
87 unsigned long guest_time;
88 long cguest_time;
89 unsigned long start_data;
90 unsigned long end_data;
91 unsigned long start_brk;
92 unsigned long arg_start;
93 unsigned long arg_end;
94 unsigned long env_start;
95 unsigned long env_end;
96 int exit_code;
97 } gate_procfs_proc_stat_t;
98
99 8 static gate_bool_t gate_procfs_load_proc_stat(int pid, gate_procfs_proc_stat_t* procstat)
100 {
101 8 gate_bool_t ret = false;
102 8 char file_path[GATE_MAX_FILEPATH_LENGTH] = GATE_INIT_EMPTY;
103 FILE* file;
104 int readcount;
105 do
106 {
107 8 gate_str_print(file_path, sizeof(file_path) - 1,
108 GATE_PRINT_CSTR, "/proc/",
109 GATE_PRINT_UI64, (gate_uint64_t)pid,
110 GATE_PRINT_CSTR, "/stat",
111 GATE_PRINT_END);
112
113 8 file = fopen(file_path, "r");
114
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (file == NULL)
115 {
116 break;
117 }
118 8 readcount = fscanf(file,
119 "%d %s %c %d %d "
120 "%d %d %d %u "
121 "%lu %lu %lu %lu "
122 "%lu %lu %lld %lld "
123 "%lld %lld %lld %lld "
124 "%llu %lu %ld %lu "
125 "%lu %lu %lu %lu %lu "
126 "%lu %lu %lu %lu %lu "
127 "%lu %lu %d %d "
128 "%u %u %llu "
129 "%lu %ld %lu %lu "
130 "%lu %lu %lu "
131 "%lu %lu %d",
132 &procstat->pid, &procstat->comm[0], &procstat->state, &procstat->ppid, &procstat->pgrp,
133 &procstat->session, &procstat->tty_nr, &procstat->tpgid, &procstat->flags,
134 &procstat->minflt, &procstat->cminflt, &procstat->majflt, &procstat->cmajflt,
135 &procstat->utime, &procstat->stime, &procstat->cutime, &procstat->cstime,
136 &procstat->priority, &procstat->nice, &procstat->num_threads, &procstat->itrealvalue,
137 &procstat->starttime, &procstat->vsize, &procstat->rss, &procstat->rsslim,
138 &procstat->startcode, &procstat->endcode, &procstat->startstack, &procstat->kstkesp, &procstat->kstkeip,
139 &procstat->signal, &procstat->blocked, &procstat->sigignore, &procstat->sigcatch, &procstat->wchan,
140 &procstat->nswap, &procstat->cnswap, &procstat->exit_signal, &procstat->processor,
141 &procstat->rt_priority, &procstat->policy, &procstat->delayacct_blkio_ticks,
142 &procstat->guest_time, &procstat->cguest_time, &procstat->start_data, &procstat->end_data,
143 &procstat->start_brk, &procstat->arg_start, &procstat->arg_end,
144 &procstat->env_start, &procstat->env_end, &procstat->exit_code
145 );
146 8 fclose(file);
147
148 8 ret = (readcount >= 48) ? true : false;
149 } while (0);
150 8 return ret;
151 }
152
153 8 static gate_int64_t gate_procfs_get_uptime_ms(void)
154 {
155 struct sysinfo info;
156 8 gate_int64_t up_time = -1;
157 8 float num = 0.0f;
158 8 FILE* file = fopen("/proc/uptime", "r");
159
160
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (file != NULL)
161 {
162
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (fscanf(file, "%f", &num) == 1)
163 {
164 8 up_time = (gate_int64_t)(num * 1000.0f);
165 }
166 8 fclose(file);
167 }
168
169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (up_time < 0)
170 {
171 gate_mem_clear(&info, sizeof(info));
172 if (sysinfo(&info) == 0)
173 {
174 up_time = (gate_int64_t)(info.uptime * 1000.0f);
175 }
176 }
177 8 return up_time;
178 }
179
180
181 typedef struct
182 {
183 unsigned long size;
184 unsigned long resident;
185 unsigned long share;
186 unsigned long text;
187 unsigned long lib;
188 unsigned long data;
189 unsigned long dt;
190 } gate_procfs_memstat_t;
191
192
193 8 static gate_bool_t gate_procfs_get_memstat(int pid, gate_procfs_memstat_t* memstat)
194 {
195 8 gate_bool_t ret = false;
196 8 char file_path[GATE_MAX_FILEPATH_LENGTH] = GATE_INIT_EMPTY;
197 FILE* file;
198 int readcount;
199 do
200 {
201 8 gate_str_print(file_path, sizeof(file_path) - 1,
202 GATE_PRINT_CSTR, "/proc/",
203 GATE_PRINT_UI64, (gate_uint64_t)pid,
204 GATE_PRINT_CSTR, "/statm",
205 GATE_PRINT_END);
206 8 file = fopen(file_path, "r");
207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (file == NULL)
208 {
209 break;
210 }
211 8 readcount = fscanf(file, "%lu %lu %lu %lu %lu %lu %lu",
212 &memstat->size, &memstat->resident, &memstat->share, &memstat->text,
213 &memstat->lib, &memstat->data, &memstat->dt
214 );
215 8 fclose(file);
216 8 ret = (readcount >= 7) ? true : false;
217 } while (0);
218 8 return ret;
219 }
220
221 8 static gate_uint64_t gate_procfs_get_open_fds(int pid)
222 {
223 8 gate_uint64_t count = 0;
224 8 struct dirent* dir_entry = NULL;
225 DIR* dir_ptr;
226 8 char dir_path[GATE_MAX_FILEPATH_LENGTH] = GATE_INIT_EMPTY;
227
228 8 gate_str_print(dir_path, sizeof(dir_path) - 1,
229 GATE_PRINT_CSTR, "/proc/",
230 GATE_PRINT_UI64, (gate_uint64_t)pid,
231 GATE_PRINT_CSTR, "/fd/",
232 GATE_PRINT_END);
233
234
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (NULL != (dir_ptr = opendir(dir_path)))
235 {
236
2/2
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 8 times.
65 while ((dir_entry = readdir(dir_ptr)))
237 {
238 57 ++count;
239 }
240 8 closedir(dir_ptr);
241 }
242 8 return count;
243 }
244
245 8 static gate_size_t gate_procfs_get_exe_path(int pid, char* exe_path, gate_size_t exe_path_len)
246 {
247 char link_path[GATE_MAX_FILEPATH_LENGTH];
248 ssize_t exe_path_used;
249 8 gate_str_print(link_path, sizeof(link_path) - 1,
250 GATE_PRINT_CSTR, "/proc/",
251 GATE_PRINT_UI64, (gate_uint64_t)pid,
252 GATE_PRINT_CSTR, "/exe",
253 GATE_PRINT_END);
254 8 exe_path_used = readlink(link_path, exe_path, exe_path_len - 1);
255
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (exe_path_used > 0)
256 {
257 8 exe_path[exe_path_used] = 0;
258 8 return (gate_size_t)exe_path_used;
259 }
260 else
261 {
262 return 0;
263 }
264 }
265
266 8 static gate_bool_t gate_procfs_get_exe_owner(int pid, int* uid, int* gid)
267 {
268 8 gate_bool_t ret = false;
269 struct stat buf;
270 char pid_path[GATE_MAX_FILEPATH_LENGTH];
271 8 gate_str_print(pid_path, sizeof(pid_path) - 1,
272 GATE_PRINT_CSTR, "/proc/",
273 GATE_PRINT_UI64, (gate_uint64_t)pid,
274 GATE_PRINT_END);
275
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (0 == stat(pid_path, &buf))
276 {
277
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (uid != NULL) *uid = (int)buf.st_uid;
278
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (gid != NULL) *gid = (int)buf.st_gid;
279 8 ret = true;
280 }
281
282 8 return ret;
283 }
284
285
286 #endif
287
288 #endif
289