Skip to content

Commit f5f571e

Browse files
committed
Extract string writing/buffer handling into some callback
1 parent c2b0bbf commit f5f571e

3 files changed

Lines changed: 113 additions & 115 deletions

File tree

linux/CGroupUtils.c

Lines changed: 110 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,45 @@ in the source distribution for its full text.
1010
#include "XUtils.h"
1111

1212

13-
static bool CGroup_filterName_internal(const char *cgroup, char* buf, size_t bufsize) {
13+
typedef struct StrBuf_state {
14+
char *buf;
15+
size_t size;
16+
size_t pos;
17+
} StrBuf_state;
18+
19+
typedef bool (*StrBuf_putc_t)(StrBuf_state* p, char c);
20+
21+
static bool StrBuf_putc_count(StrBuf_state* p, ATTR_UNUSED char c) {
22+
p->pos++;
23+
return true;
24+
}
25+
26+
static bool StrBuf_putc_write(StrBuf_state* p, char c) {
27+
if (p->pos >= p->size)
28+
return false;
29+
30+
p->buf[p->pos] = c;
31+
p->pos++;
32+
return true;
33+
}
34+
35+
static bool StrBuf_putsn(StrBuf_state* p, StrBuf_putc_t w, const char* s, size_t count) {
36+
while (count--)
37+
if (!w(p, *s++))
38+
return false;
39+
40+
return true;
41+
}
42+
43+
static bool StrBuf_putsz(StrBuf_state* p, StrBuf_putc_t w, const char* s) {
44+
while (*s)
45+
if (!w(p, *s++))
46+
return false;
47+
48+
return true;
49+
}
50+
51+
static bool CGroup_filterName_internal(const char *cgroup, StrBuf_state* s, StrBuf_putc_t w) {
1452
const char* str_slice_suffix = ".slice";
1553
const char* str_system_slice = "system.slice";
1654
const char* str_user_slice = "user.slice";
@@ -22,21 +60,19 @@ static bool CGroup_filterName_internal(const char *cgroup, char* buf, size_t buf
2260

2361
const char* str_nspawn_scope_prefix = "machine-";
2462
const char* str_nspawn_monitor_label = "/supervisor";
63+
const char* str_nspawn_payload_label = "/payload";
2564

2665
const char* str_service_suffix = ".service";
2766
const char* str_scope_suffix = ".scope";
2867

29-
while(*cgroup) {
68+
while (*cgroup) {
3069
if ('/' == *cgroup) {
3170
while ('/' == *cgroup)
3271
cgroup++;
3372

34-
if (!bufsize)
73+
if (!w(s, '/'))
3574
return false;
3675

37-
*buf++ = '/';
38-
bufsize--;
39-
4076
continue;
4177
}
4278

@@ -50,14 +86,9 @@ static bool CGroup_filterName_internal(const char *cgroup, char* buf, size_t buf
5086
if (*cgroup && *cgroup != '/')
5187
goto handle_default;
5288

53-
if (bufsize < 3)
89+
if (!StrBuf_putsz(s, w, "[S]"))
5490
return false;
5591

56-
*buf++ = '[';
57-
*buf++ = 'S';
58-
*buf++ = ']';
59-
bufsize -= 3;
60-
6192
continue;
6293
}
6394

@@ -67,14 +98,9 @@ static bool CGroup_filterName_internal(const char *cgroup, char* buf, size_t buf
6798
if (*cgroup && *cgroup != '/')
6899
goto handle_default;
69100

70-
if (bufsize < 3)
101+
if (!StrBuf_putsz(s, w, "[M]"))
71102
return false;
72103

73-
*buf++ = '[';
74-
*buf++ = 'M';
75-
*buf++ = ']';
76-
bufsize -= 3;
77-
78104
continue;
79105
}
80106

@@ -84,14 +110,9 @@ static bool CGroup_filterName_internal(const char *cgroup, char* buf, size_t buf
84110
if (*cgroup && *cgroup != '/')
85111
goto handle_default;
86112

87-
if (bufsize < 3)
113+
if (!StrBuf_putsz(s, w, "[U]"))
88114
return false;
89115

90-
*buf++ = '[';
91-
*buf++ = 'U';
92-
*buf++ = ']';
93-
bufsize -= 3;
94-
95116
if (!String_startsWith(cgroup, str_user_slice_prefix))
96117
continue;
97118

@@ -103,39 +124,32 @@ static bool CGroup_filterName_internal(const char *cgroup, char* buf, size_t buf
103124

104125
const size_t sliceNameLen = sliceSpec - (cgroup + strlen(str_user_slice_prefix));
105126

106-
if (bufsize < sliceNameLen + 1)
127+
s->pos--;
128+
if (!w(s, ':'))
107129
return false;
108130

109-
buf[-1] = ':';
131+
if (!StrBuf_putsn(s, w, cgroup + strlen(str_user_slice_prefix), sliceNameLen))
132+
return false;
110133

111-
cgroup += strlen(str_user_slice_prefix);
112-
while(cgroup < sliceSpec) {
113-
*buf++ = *cgroup++;
114-
bufsize--;
115-
}
116-
cgroup = userSliceSlash;
134+
if (!w(s, ']'))
135+
return false;
117136

118-
*buf++ = ']';
119-
bufsize--;
137+
cgroup = userSliceSlash;
120138

121139
continue;
122140
}
123141

124142
if (labelLen > strlen(str_slice_suffix) && String_startsWith(nextSlash - strlen(str_slice_suffix), str_slice_suffix)) {
125143
const size_t sliceNameLen = labelLen - strlen(str_slice_suffix);
126-
if (bufsize < 2 + sliceNameLen)
127-
return false;
128144

129-
*buf++ = '[';
130-
bufsize--;
145+
if (!w(s, '['))
146+
return false;
131147

132-
for(size_t i = sliceNameLen; i; i--) {
133-
*buf++ = *cgroup++;
134-
bufsize--;
135-
}
148+
if (!StrBuf_putsn(s, w, cgroup, sliceNameLen))
149+
return false;
136150

137-
*buf++ = ']';
138-
bufsize--;
151+
if (!w(s, ']'))
152+
return false;
139153

140154
cgroup = nextSlash;
141155

@@ -144,48 +158,34 @@ static bool CGroup_filterName_internal(const char *cgroup, char* buf, size_t buf
144158

145159
if (String_startsWith(cgroup, str_lxc_payload_prefix)) {
146160
const size_t cgroupNameLen = labelLen - strlen(str_lxc_payload_prefix);
147-
if (bufsize < 6 + cgroupNameLen)
161+
162+
if (!StrBuf_putsz(s, w, "[lxc:"))
148163
return false;
149164

150-
*buf++ = '[';
151-
*buf++ = 'l';
152-
*buf++ = 'x';
153-
*buf++ = 'c';
154-
*buf++ = ':';
155-
bufsize -= 5;
156-
157-
cgroup += strlen(str_lxc_payload_prefix);
158-
while(cgroup < nextSlash) {
159-
*buf++ = *cgroup++;
160-
bufsize--;
161-
}
165+
if (!StrBuf_putsn(s, w, cgroup + strlen(str_lxc_payload_prefix), cgroupNameLen))
166+
return false;
167+
168+
if (!w(s, ']'))
169+
return false;
162170

163-
*buf++ = ']';
164-
bufsize--;
171+
cgroup = nextSlash;
165172

166173
continue;
167174
}
168175

169176
if (String_startsWith(cgroup, str_lxc_monitor_prefix)) {
170177
const size_t cgroupNameLen = labelLen - strlen(str_lxc_monitor_prefix);
171-
if (bufsize < 6 + cgroupNameLen)
178+
179+
if (!StrBuf_putsz(s, w, "[LXC:"))
172180
return false;
173181

174-
*buf++ = '[';
175-
*buf++ = 'L';
176-
*buf++ = 'X';
177-
*buf++ = 'C';
178-
*buf++ = ':';
179-
bufsize -= 5;
180-
181-
cgroup += strlen(str_lxc_monitor_prefix);
182-
while(cgroup < nextSlash) {
183-
*buf++ = *cgroup++;
184-
bufsize--;
185-
}
182+
if (!StrBuf_putsn(s, w, cgroup + strlen(str_lxc_monitor_prefix), cgroupNameLen))
183+
return false;
186184

187-
*buf++ = ']';
188-
bufsize--;
185+
if (!w(s, ']'))
186+
return false;
187+
188+
cgroup = nextSlash;
189189

190190
continue;
191191
}
@@ -202,14 +202,9 @@ static bool CGroup_filterName_internal(const char *cgroup, char* buf, size_t buf
202202
continue;
203203
}
204204

205-
if (bufsize < serviceNameLen)
205+
if (!StrBuf_putsn(s, w, cgroup, serviceNameLen))
206206
return false;
207207

208-
for(size_t i = serviceNameLen; i; i--) {
209-
*buf++ = *cgroup++;
210-
bufsize--;
211-
}
212-
213208
cgroup = nextSlash;
214209

215210
continue;
@@ -220,42 +215,32 @@ static bool CGroup_filterName_internal(const char *cgroup, char* buf, size_t buf
220215

221216
if (String_startsWith(cgroup, str_nspawn_scope_prefix)) {
222217
const size_t machineScopeNameLen = scopeNameLen - strlen(str_nspawn_scope_prefix);
223-
if (bufsize < 6 + machineScopeNameLen)
224-
return false;
225218

226219
const bool is_monitor = String_startsWith(nextSlash, str_nspawn_monitor_label);
227220

228-
*buf++ = '[';
229-
*buf++ = is_monitor ? 'S' : 's';
230-
*buf++ = is_monitor ? 'N' : 'n';
231-
*buf++ = is_monitor ? 'C' : 'c';
232-
*buf++ = ':';
233-
bufsize -= 5;
221+
if (!StrBuf_putsz(s, w, is_monitor ? "[SNC:" : "[snc:"))
222+
return false;
234223

235-
cgroup += strlen(str_nspawn_scope_prefix);
236-
for(size_t i = machineScopeNameLen; i; i--) {
237-
*buf++ = *cgroup++;
238-
bufsize--;
239-
}
224+
if (!StrBuf_putsn(s, w, cgroup + strlen(str_nspawn_scope_prefix), machineScopeNameLen))
225+
return false;
240226

241-
*buf++ = ']';
242-
bufsize--;
227+
if (!w(s, ']'))
228+
return false;
243229

244230
cgroup = nextSlash;
231+
if (String_startsWith(nextSlash, str_nspawn_monitor_label))
232+
cgroup += strlen(str_nspawn_monitor_label);
233+
else if (String_startsWith(nextSlash, str_nspawn_payload_label))
234+
cgroup += strlen(str_nspawn_payload_label);
245235

246236
continue;
247237
}
248238

249-
if (bufsize < 1 + scopeNameLen)
239+
if (!w(s, '!'))
250240
return false;
251241

252-
*buf++ = '!';
253-
bufsize--;
254-
255-
for(size_t i = scopeNameLen; i; i--) {
256-
*buf++ = *cgroup++;
257-
bufsize--;
258-
}
242+
if (!StrBuf_putsn(s, w, cgroup, scopeNameLen))
243+
return false;
259244

260245
cgroup = nextSlash;
261246

@@ -266,20 +251,33 @@ static bool CGroup_filterName_internal(const char *cgroup, char* buf, size_t buf
266251
// Default behavior: Copy the full label
267252
cgroup = labelStart;
268253

269-
if (bufsize < (size_t)(nextSlash - cgroup))
254+
if (!StrBuf_putsn(s, w, cgroup, labelLen))
270255
return false;
271-
272-
while(cgroup < nextSlash) {
273-
*buf++ = *cgroup++;
274-
bufsize--;
275-
}
276256
}
277257

278258
return true;
279259
}
280260

281-
bool CGroup_filterName(const char *cgroup, char* buf, size_t bufsize) {
282-
memset(buf, 0, bufsize);
261+
char* CGroup_filterName(const char *cgroup) {
262+
StrBuf_state s = {
263+
.buf = NULL,
264+
.size = 0,
265+
.pos = 0,
266+
};
267+
268+
if (!CGroup_filterName_internal(cgroup, &s, StrBuf_putc_count)) {
269+
return NULL;
270+
}
271+
272+
s.buf = xCalloc(s.pos + 1, sizeof(char));
273+
s.size = s.pos;
274+
s.pos = 0;
275+
276+
if (!CGroup_filterName_internal(cgroup, &s, StrBuf_putc_write)) {
277+
free(s.buf);
278+
return NULL;
279+
}
283280

284-
return CGroup_filterName_internal(cgroup, buf, bufsize - 1);
281+
s.buf[s.size] = '\0';
282+
return s.buf;
285283
}

linux/CGroupUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ in the source distribution for its full text.
1111
#include <stddef.h>
1212

1313

14-
bool CGroup_filterName(const char *cgroup, char* buf, size_t bufsize);
14+
char* CGroup_filterName(const char *cgroup);
1515

1616
#endif /* HEADER_CGroupUtils */

linux/LinuxProcessList.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -872,8 +872,8 @@ static void LinuxProcessList_readCGroupFile(LinuxProcess* process, openat_arg_t
872872
fclose(file);
873873
free_and_xStrdup(&process->cgroup, output);
874874

875-
char* cgroup_short = xCalloc(strlen(process->cgroup) + 1, 1);
876-
if (CGroup_filterName(process->cgroup, cgroup_short, strlen(process->cgroup) + 1)) {
875+
char* cgroup_short = CGroup_filterName(process->cgroup);
876+
if (cgroup_short) {
877877
free_and_xStrdup(&process->cgroup_short, cgroup_short);
878878
} else {
879879
free(process->cgroup_short);

0 commit comments

Comments
 (0)