"Fossies" - the Fresh Open Source Software Archive 
Member "dhcpcd-9.4.1/compat/setproctitle.c" (22 Oct 2021, 6941 Bytes) of package /linux/misc/dhcpcd-9.4.1.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
See also the last
Fossies "Diffs" side-by-side code changes report for "setproctitle.c":
9.3.0_vs_9.3.1.
1 /*
2 * Copyright © 2010 William Ahern
3 * Copyright © 2012-2013 Guillem Jover <guillem@hadrons.org>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to permit
10 * persons to whom the Software is furnished to do so, subject to the
11 * following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
19 * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #include <errno.h>
26 #include <stddef.h>
27 #include <stdarg.h>
28 #include <stdbool.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <err.h>
32 #include <unistd.h>
33 #include <string.h>
34 //#include "local-link.h"
35
36 #include "config.h"
37
38 static struct {
39 /* Original value. */
40 char *arg0;
41
42 /* Title space available. */
43 char *base, *end;
44
45 /* Pointer to original nul character within base. */
46 char *nul;
47
48 bool warned;
49 bool reset;
50 int error;
51
52 /* Our copy of args and environment to free. */
53 int argc;
54 char **argv;
55 char **tmp_environ;
56 } SPT;
57
58
59 static inline size_t
60 spt_min(size_t a, size_t b)
61 {
62 return a < b ? a : b;
63 }
64
65 /*
66 * For discussion on the portability of the various methods, see
67 * https://lists.freebsd.org/pipermail/freebsd-stable/2008-June/043136.html
68 */
69 static int
70 spt_clearenv(void)
71 {
72 #ifdef HAVE_CLEARENV
73 return clearenv();
74 #else
75 SPT.tmp_environ = malloc(sizeof(*SPT.tmp_environ));
76 if (SPT.tmp_environ == NULL)
77 return errno;
78
79 SPT.tmp_environ[0] = NULL;
80 environ = SPT.tmp_environ;
81
82 return 0;
83 #endif
84 }
85
86 static int
87 spt_copyenv(int envc, char *envp[])
88 {
89 char **envcopy;
90 char *eq;
91 size_t envsize;
92 int i, error;
93
94 if (environ != envp)
95 return 0;
96
97 /* Make a copy of the old environ array of pointers, in case
98 * clearenv() or setenv() is implemented to free the internal
99 * environ array, because we will need to access the old environ
100 * contents to make the new copy. */
101 envsize = (size_t)(envc + 1) * sizeof(char *);
102 envcopy = malloc(envsize);
103 if (envcopy == NULL)
104 return errno;
105 memcpy(envcopy, envp, envsize);
106
107 error = spt_clearenv();
108 if (error) {
109 environ = envp;
110 free(envcopy);
111 return error;
112 }
113
114 for (i = 0; envcopy[i]; i++) {
115 eq = strchr(envcopy[i], '=');
116 if (eq == NULL)
117 continue;
118
119 *eq = '\0';
120 if (setenv(envcopy[i], eq + 1, 1) < 0)
121 error = errno;
122 *eq = '=';
123
124 if (error) {
125 #ifdef HAVE_CLEARENV
126 /* Because the old environ might not be available
127 * anymore we will make do with the shallow copy. */
128 environ = envcopy;
129 #else
130 environ = envp;
131 free(envcopy);
132 #endif
133 return error;
134 }
135 }
136
137 /* Dispose of the shallow copy, now that we've finished transfering
138 * the old environment. */
139 free(envcopy);
140
141 return 0;
142 }
143
144 static int
145 spt_copyargs(int argc, char *argv[])
146 {
147 char *tmp;
148 int i;
149
150 for (i = 1; i < argc || (i >= argc && argv[i]); i++) {
151 if (argv[i] == NULL)
152 continue;
153
154 tmp = strdup(argv[i]);
155 if (tmp == NULL)
156 return errno;
157
158 argv[i] = tmp;
159 }
160
161 return 0;
162 }
163
164 void
165 setproctitle_init(int argc, char *argv[], char *envp[])
166 {
167 char *base, *end, *nul, *tmp;
168 int i, envc, error;
169
170 /* Try to make sure we got called with main() arguments. */
171 if (argc < 0)
172 return;
173
174 base = argv[0];
175 if (base == NULL)
176 return;
177
178 nul = &base[strlen(base)];
179 end = nul + 1;
180
181 for (i = 0; i < argc || (i >= argc && argv[i]); i++) {
182 if (argv[i] == NULL || argv[i] != end)
183 continue;
184
185 end = argv[i] + strlen(argv[i]) + 1;
186 }
187
188 for (i = 0; envp[i]; i++) {
189 if (envp[i] != end)
190 continue;
191
192 end = envp[i] + strlen(envp[i]) + 1;
193 }
194 envc = i;
195
196 SPT.arg0 = strdup(argv[0]);
197 if (SPT.arg0 == NULL) {
198 SPT.error = errno;
199 return;
200 }
201
202 tmp = strdup(getprogname());
203 if (tmp == NULL) {
204 SPT.error = errno;
205 return;
206 }
207 setprogname(tmp);
208
209 error = spt_copyenv(envc, envp);
210 if (error) {
211 SPT.error = error;
212 return;
213 }
214
215 error = spt_copyargs(argc, argv);
216 if (error) {
217 SPT.error = error;
218 return;
219 }
220
221 SPT.argc = argc;
222 SPT.argv = argv;
223
224 SPT.nul = nul;
225 SPT.base = base;
226 SPT.end = end;
227 }
228
229 void
230 setproctitle_fini(void)
231 {
232 int i;
233
234 free(SPT.arg0);
235 SPT.arg0 = NULL;
236
237 for (i = 1; i < SPT.argc; i++) {
238 if (SPT.argv[i] != NULL)
239 free(SPT.argv[i]);
240 }
241 SPT.argc = 0;
242
243 free(SPT.tmp_environ);
244 SPT.tmp_environ = NULL;
245 }
246
247 #ifndef SPT_MAXTITLE
248 #define SPT_MAXTITLE 255
249 #endif
250
251 __printflike(1, 2) static void
252 setproctitle_impl(const char *fmt, ...)
253 {
254 /* Use buffer in case argv[0] is passed. */
255 char buf[SPT_MAXTITLE + 1];
256 va_list ap;
257 char *nul;
258 int l;
259 size_t len, base_len;
260
261 if (SPT.base == NULL) {
262 if (!SPT.warned) {
263 warnx("setproctitle not initialized, please either call "
264 "setproctitle_init() or link against libbsd-ctor.");
265 SPT.warned = true;
266 }
267 return;
268 }
269
270 if (fmt) {
271 if (fmt[0] == '-') {
272 /* Skip program name prefix. */
273 fmt++;
274 len = 0;
275 } else {
276 /* Print program name heading for grep. */
277 l = snprintf(buf, sizeof(buf), "%s: ", getprogname());
278 if (l <= 0)
279 return;
280 len = (size_t)l;
281 }
282
283 va_start(ap, fmt);
284 l = vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
285 va_end(ap);
286 } else {
287 len = 0;
288 l = snprintf(buf, sizeof(buf), "%s", SPT.arg0);
289 }
290
291 if (l <= 0) {
292 SPT.error = errno;
293 return;
294 }
295 len += (size_t)l;
296
297 base_len = (size_t)(SPT.end - SPT.base);
298 if (!SPT.reset) {
299 memset(SPT.base, 0, base_len);
300 SPT.reset = true;
301 } else {
302 memset(SPT.base, 0, spt_min(sizeof(buf), base_len));
303 }
304
305 len = spt_min(len, spt_min(sizeof(buf), base_len) - 1);
306 memcpy(SPT.base, buf, len);
307 nul = &SPT.base[len];
308
309 if (nul < SPT.nul) {
310 *SPT.nul = '.';
311 } else if (nul == SPT.nul && &nul[1] < SPT.end) {
312 *SPT.nul = ' ';
313 *++nul = '\0';
314 }
315 }
316 libbsd_symver_default(setproctitle, setproctitle_impl, LIBBSD_0.5);
317
318 /* The original function introduced in 0.2 was a stub, it only got implemented
319 * in 0.5, make the implementation available in the old version as an alias
320 * for code linking against that version, and change the default to use the
321 * new version, so that new code depends on the implemented version. */
322 #ifdef HAVE_TYPEOF
323 extern __typeof__(setproctitle_impl)
324 setproctitle_stub
325 __attribute__((__alias__("setproctitle_impl")));
326 #else
327 void
328 setproctitle_stub(const char *fmt, ...)
329 __attribute__((__alias__("setproctitle_impl")));
330 #endif
331 libbsd_symver_variant(setproctitle, setproctitle_stub, LIBBSD_0.2);