]> git.ipfire.org Git - people/ms/systemd.git/blame - util.c
add some test script output
[people/ms/systemd.git] / util.c
CommitLineData
60918275
LP
1/*-*- Mode: C; c-basic-offset: 8 -*-*/
2
3#include <assert.h>
4#include <string.h>
5#include <unistd.h>
6#include <errno.h>
85261803 7#include <stdlib.h>
034c6ed7
LP
8#include <signal.h>
9#include <stdio.h>
60918275
LP
10
11#include "macro.h"
12#include "util.h"
13
14usec_t now(clockid_t clock) {
15 struct timespec ts;
16
17 assert_se(clock_gettime(clock, &ts) == 0);
18
19 return timespec_load(&ts);
20}
21
22usec_t timespec_load(const struct timespec *ts) {
23 assert(ts);
24
25 return
26 (usec_t) ts->tv_sec * USEC_PER_SEC +
27 (usec_t) ts->tv_nsec / NSEC_PER_USEC;
28}
29
30struct timespec *timespec_store(struct timespec *ts, usec_t u) {
31 assert(ts);
32
33 ts->tv_sec = (time_t) (u / USEC_PER_SEC);
34 ts->tv_nsec = (long int) ((u % USEC_PER_SEC) * NSEC_PER_USEC);
35
36 return ts;
37}
38
39usec_t timeval_load(const struct timeval *tv) {
40 assert(tv);
41
42 return
43 (usec_t) tv->tv_sec * USEC_PER_SEC +
44 (usec_t) tv->tv_usec;
45}
46
47struct timeval *timeval_store(struct timeval *tv, usec_t u) {
48 assert(tv);
49
50 tv->tv_sec = (time_t) (u / USEC_PER_SEC);
51 tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC);
52
53 return tv;
54}
55
56bool endswith(const char *s, const char *postfix) {
57 size_t sl, pl;
58
59 assert(s);
60 assert(postfix);
61
62 sl = strlen(s);
63 pl = strlen(postfix);
64
65 if (sl < pl)
66 return false;
67
68 return memcmp(s + sl - pl, postfix, pl) == 0;
69}
70
71bool startswith(const char *s, const char *prefix) {
72 size_t sl, pl;
73
74 assert(s);
75 assert(prefix);
76
77 sl = strlen(s);
78 pl = strlen(prefix);
79
80 if (sl < pl)
81 return false;
82
83 return memcmp(s, prefix, pl) == 0;
84}
85
42f4e3c4 86int close_nointr(int fd) {
60918275
LP
87 assert(fd >= 0);
88
89 for (;;) {
90 int r;
91
92 if ((r = close(fd)) >= 0)
93 return r;
94
95 if (errno != EINTR)
96 return r;
97 }
98}
85261803
LP
99
100int parse_boolean(const char *v) {
101 assert(v);
102
44d8db9e 103 if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
85261803 104 return 1;
44d8db9e 105 else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
85261803
LP
106 return 0;
107
108 return -EINVAL;
109}
110
111int safe_atou(const char *s, unsigned *ret_u) {
112 char *x = NULL;
034c6ed7 113 unsigned long l;
85261803
LP
114
115 assert(s);
116 assert(ret_u);
117
118 errno = 0;
119 l = strtoul(s, &x, 0);
120
121 if (!x || *x || errno)
122 return errno ? -errno : -EINVAL;
123
034c6ed7 124 if ((unsigned long) (unsigned) l != l)
85261803
LP
125 return -ERANGE;
126
127 *ret_u = (unsigned) l;
128 return 0;
129}
130
131int safe_atoi(const char *s, int *ret_i) {
132 char *x = NULL;
034c6ed7 133 long l;
85261803
LP
134
135 assert(s);
136 assert(ret_i);
137
138 errno = 0;
139 l = strtol(s, &x, 0);
140
141 if (!x || *x || errno)
142 return errno ? -errno : -EINVAL;
143
034c6ed7 144 if ((long) (int) l != l)
85261803
LP
145 return -ERANGE;
146
034c6ed7
LP
147 *ret_i = (int) l;
148 return 0;
149}
150
151int safe_atolu(const char *s, long unsigned *ret_lu) {
152 char *x = NULL;
153 unsigned long l;
154
155 assert(s);
156 assert(ret_lu);
157
158 errno = 0;
159 l = strtoul(s, &x, 0);
160
161 if (!x || *x || errno)
162 return errno ? -errno : -EINVAL;
163
164 *ret_lu = l;
165 return 0;
166}
167
168int safe_atoli(const char *s, long int *ret_li) {
169 char *x = NULL;
170 long l;
171
172 assert(s);
173 assert(ret_li);
174
175 errno = 0;
176 l = strtol(s, &x, 0);
177
178 if (!x || *x || errno)
179 return errno ? -errno : -EINVAL;
180
181 *ret_li = l;
182 return 0;
183}
184
185int safe_atollu(const char *s, long long unsigned *ret_llu) {
186 char *x = NULL;
187 unsigned long long l;
188
189 assert(s);
190 assert(ret_llu);
191
192 errno = 0;
193 l = strtoull(s, &x, 0);
194
195 if (!x || *x || errno)
196 return errno ? -errno : -EINVAL;
197
198 *ret_llu = l;
199 return 0;
200}
201
202int safe_atolli(const char *s, long long int *ret_lli) {
203 char *x = NULL;
204 long long l;
205
206 assert(s);
207 assert(ret_lli);
208
209 errno = 0;
210 l = strtoll(s, &x, 0);
211
212 if (!x || *x || errno)
213 return errno ? -errno : -EINVAL;
214
215 *ret_lli = l;
85261803
LP
216 return 0;
217}
a41e8209 218
a41e8209
LP
219/* Split a string into words. */
220char *split_spaces(const char *c, size_t *l, char **state) {
221 char *current;
222
223 current = *state ? *state : (char*) c;
224
225 if (!*current || *c == 0)
226 return NULL;
227
228 current += strspn(current, WHITESPACE);
229 *l = strcspn(current, WHITESPACE);
230 *state = current+*l;
231
232 return (char*) current;
233}
034c6ed7
LP
234
235/* Split a string into words, but consider strings enclosed in '' and
236 * "" as words even if they include spaces. */
237char *split_quoted(const char *c, size_t *l, char **state) {
238 char *current;
239
240 current = *state ? *state : (char*) c;
241
242 if (!*current || *c == 0)
243 return NULL;
244
245 current += strspn(current, WHITESPACE);
246
247 if (*current == '\'') {
248 current ++;
249 *l = strcspn(current, "'");
250 *state = current+*l;
251
252 if (**state == '\'')
253 (*state)++;
254 } else if (*current == '\"') {
255 current ++;
256 *l = strcspn(current+1, "\"");
257 *state = current+*l;
258
259 if (**state == '\"')
260 (*state)++;
261 } else {
262 *l = strcspn(current, WHITESPACE);
263 *state = current+*l;
264 }
265
44d8db9e
LP
266 /* FIXME: Cannot deal with strings that have spaces AND ticks
267 * in them */
268
034c6ed7
LP
269 return (char*) current;
270}
271
272const char *sigchld_code(int code) {
273
274 if (code == CLD_EXITED)
275 return "exited";
276 else if (code == CLD_KILLED)
277 return "killed";
278 else if (code == CLD_DUMPED)
279 return "dumped";
280 else if (code == CLD_TRAPPED)
281 return "trapped";
282 else if (code == CLD_STOPPED)
283 return "stopped";
284 else if (code == CLD_CONTINUED)
285 return "continued";
286
287 return "unknown";
288}
289
290int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
291 int r;
292 FILE *f;
293 char fn[132], line[256], *p;
294 long long unsigned ppid;
295
296 assert(pid >= 0);
297 assert(_ppid);
298
299 assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%llu/stat", (unsigned long long) pid) < (int) (sizeof(fn)-1));
300 fn[sizeof(fn)-1] = 0;
301
302 if (!(f = fopen(fn, "r")))
303 return -errno;
304
305 if (!(fgets(line, sizeof(line), f))) {
306 r = -errno;
307 fclose(f);
308 return r;
309 }
310
311 fclose(f);
312
313 /* Let's skip the pid and comm fields. The latter is enclosed
314 * in () but does not escape any () in its value, so let's
315 * skip over it manually */
316
317 if (!(p = strrchr(line, ')')))
318 return -EIO;
319
320 p++;
321
322 if (sscanf(p, " "
323 "%*c " /* state */
324 "%llu ", /* ppid */
325 &ppid) != 1)
326 return -EIO;
327
328 if ((long long unsigned) (pid_t) ppid != ppid)
329 return -ERANGE;
330
331 *_ppid = (pid_t) ppid;
332
333 return 0;
334}
335
336int write_one_line_file(const char *fn, const char *line) {
337 FILE *f;
338 int r;
339
340 assert(fn);
341 assert(line);
342
343 if (!(f = fopen(fn, "we")))
344 return -errno;
345
346 if (fputs(line, f) < 0) {
347 r = -errno;
348 goto finish;
349 }
350
351 r = 0;
352finish:
353 fclose(f);
354 return r;
355}
356
357int read_one_line_file(const char *fn, char **line) {
358 FILE *f;
359 int r;
360 char t[64], *c;
361
362 assert(fn);
363 assert(line);
364
365 if (!(f = fopen(fn, "re")))
366 return -errno;
367
368 if (!(fgets(t, sizeof(t), f))) {
369 r = -errno;
370 goto finish;
371 }
372
373 if (!(c = strdup(t))) {
374 r = -ENOMEM;
375 goto finish;
376 }
377
378 *line = c;
379 r = 0;
380
381finish:
382 fclose(f);
383 return r;
384}
44d8db9e
LP
385
386char *strappend(const char *s, const char *suffix) {
387 size_t a, b;
388 char *r;
389
390 assert(s);
391 assert(suffix);
392
393 a = strlen(s);
394 b = strlen(suffix);
395
396 if (!(r = new(char, a+b+1)))
397 return NULL;
398
399 memcpy(r, s, a);
400 memcpy(r+a, suffix, b);
401 r[a+b] = 0;
402
403 return r;
404}
87f0e418
LP
405
406int readlink_malloc(const char *p, char **r) {
407 size_t l = 100;
408
409 assert(p);
410 assert(r);
411
412 for (;;) {
413 char *c;
414 ssize_t n;
415
416 if (!(c = new(char, l)))
417 return -ENOMEM;
418
419 if ((n = readlink(p, c, l-1)) < 0) {
420 int ret = -errno;
421 free(c);
422 return ret;
423 }
424
425 if ((size_t) n < l-1) {
426 c[n] = 0;
427 *r = c;
428 return 0;
429 }
430
431 free(c);
432 l *= 2;
433 }
434}
435
436char *file_name_from_path(const char *p) {
437 char *r;
438
439 assert(p);
440
441 if ((r = strrchr(p, '/')))
442 return r + 1;
443
444 return (char*) p;
445}
0301abf4
LP
446
447bool path_is_absolute(const char *p) {
448 assert(p);
449
450 return p[0] == '/';
451}
452
453bool is_path(const char *p) {
454
455 return !!strchr(p, '/');
456}
457
458char *path_make_absolute(const char *p, const char *prefix) {
459 char *r;
460
461 assert(p);
462
463 if (path_is_absolute(p) || !prefix)
464 return strdup(p);
465
466 if (asprintf(&r, "%s/%s", prefix, p) < 0)
467 return NULL;
468
469 return r;
470}