@@ -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}
0 commit comments