]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/util.c
systemctl: provide compatibility implementations for various sysv utilities
[thirdparty/systemd.git] / src / util.c
CommitLineData
60918275
LP
1/*-*- Mode: C; c-basic-offset: 8 -*-*/
2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
60918275
LP
22#include <assert.h>
23#include <string.h>
24#include <unistd.h>
25#include <errno.h>
85261803 26#include <stdlib.h>
034c6ed7
LP
27#include <signal.h>
28#include <stdio.h>
1dccbe19
LP
29#include <syslog.h>
30#include <sched.h>
31#include <sys/resource.h>
ef886c6a 32#include <linux/sched.h>
a9f5d454
LP
33#include <sys/types.h>
34#include <sys/stat.h>
3a0ecb08 35#include <fcntl.h>
a0d40ac5 36#include <dirent.h>
601f6a1e
LP
37#include <sys/ioctl.h>
38#include <linux/vt.h>
39#include <linux/tiocl.h>
80876c20
LP
40#include <termios.h>
41#include <stdarg.h>
42#include <sys/inotify.h>
43#include <sys/poll.h>
8d567588 44#include <libgen.h>
3177a7fa 45#include <ctype.h>
5b6319dc 46#include <sys/prctl.h>
60918275
LP
47
48#include "macro.h"
49#include "util.h"
1dccbe19
LP
50#include "ioprio.h"
51#include "missing.h"
a9f5d454 52#include "log.h"
65d2ebdc 53#include "strv.h"
60918275 54
e05797fb
LP
55bool streq_ptr(const char *a, const char *b) {
56
57 /* Like streq(), but tries to make sense of NULL pointers */
58
59 if (a && b)
60 return streq(a, b);
61
62 if (!a && !b)
63 return true;
64
65 return false;
66}
67
47be870b 68usec_t now(clockid_t clock_id) {
60918275
LP
69 struct timespec ts;
70
47be870b 71 assert_se(clock_gettime(clock_id, &ts) == 0);
60918275
LP
72
73 return timespec_load(&ts);
74}
75
871d7de4
LP
76timestamp* timestamp_get(timestamp *ts) {
77 assert(ts);
78
79 ts->realtime = now(CLOCK_REALTIME);
80 ts->monotonic = now(CLOCK_MONOTONIC);
81
82 return ts;
83}
84
60918275
LP
85usec_t timespec_load(const struct timespec *ts) {
86 assert(ts);
87
88 return
89 (usec_t) ts->tv_sec * USEC_PER_SEC +
90 (usec_t) ts->tv_nsec / NSEC_PER_USEC;
91}
92
93struct timespec *timespec_store(struct timespec *ts, usec_t u) {
94 assert(ts);
95
96 ts->tv_sec = (time_t) (u / USEC_PER_SEC);
97 ts->tv_nsec = (long int) ((u % USEC_PER_SEC) * NSEC_PER_USEC);
98
99 return ts;
100}
101
102usec_t timeval_load(const struct timeval *tv) {
103 assert(tv);
104
105 return
106 (usec_t) tv->tv_sec * USEC_PER_SEC +
107 (usec_t) tv->tv_usec;
108}
109
110struct timeval *timeval_store(struct timeval *tv, usec_t u) {
111 assert(tv);
112
113 tv->tv_sec = (time_t) (u / USEC_PER_SEC);
114 tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC);
115
116 return tv;
117}
118
119bool endswith(const char *s, const char *postfix) {
120 size_t sl, pl;
121
122 assert(s);
123 assert(postfix);
124
125 sl = strlen(s);
126 pl = strlen(postfix);
127
d4d0d4db
LP
128 if (pl == 0)
129 return true;
130
60918275
LP
131 if (sl < pl)
132 return false;
133
134 return memcmp(s + sl - pl, postfix, pl) == 0;
135}
136
137bool startswith(const char *s, const char *prefix) {
138 size_t sl, pl;
139
140 assert(s);
141 assert(prefix);
142
143 sl = strlen(s);
144 pl = strlen(prefix);
145
d4d0d4db
LP
146 if (pl == 0)
147 return true;
148
60918275
LP
149 if (sl < pl)
150 return false;
151
152 return memcmp(s, prefix, pl) == 0;
153}
154
3177a7fa
MAP
155bool startswith_no_case(const char *s, const char *prefix) {
156 size_t sl, pl;
157 unsigned i;
158
159 assert(s);
160 assert(prefix);
161
162 sl = strlen(s);
163 pl = strlen(prefix);
164
165 if (pl == 0)
166 return true;
167
168 if (sl < pl)
169 return false;
170
171 for(i = 0; i < pl; ++i) {
172 if (tolower(s[i]) != tolower(prefix[i]))
173 return false;
174 }
175
176 return true;
177}
178
79d6d816
LP
179bool first_word(const char *s, const char *word) {
180 size_t sl, wl;
181
182 assert(s);
183 assert(word);
184
185 sl = strlen(s);
186 wl = strlen(word);
187
188 if (sl < wl)
189 return false;
190
d4d0d4db
LP
191 if (wl == 0)
192 return true;
193
79d6d816
LP
194 if (memcmp(s, word, wl) != 0)
195 return false;
196
d4d0d4db
LP
197 return s[wl] == 0 ||
198 strchr(WHITESPACE, s[wl]);
79d6d816
LP
199}
200
42f4e3c4 201int close_nointr(int fd) {
60918275
LP
202 assert(fd >= 0);
203
204 for (;;) {
205 int r;
206
207 if ((r = close(fd)) >= 0)
208 return r;
209
210 if (errno != EINTR)
211 return r;
212 }
213}
85261803 214
85f136b5 215void close_nointr_nofail(int fd) {
80876c20 216 int saved_errno = errno;
85f136b5
LP
217
218 /* like close_nointr() but cannot fail, and guarantees errno
219 * is unchanged */
220
221 assert_se(close_nointr(fd) == 0);
80876c20
LP
222
223 errno = saved_errno;
85f136b5
LP
224}
225
5b6319dc
LP
226void close_many(const int fds[], unsigned n_fd) {
227 unsigned i;
228
229 for (i = 0; i < n_fd; i++)
230 close_nointr_nofail(fds[i]);
231}
232
85261803
LP
233int parse_boolean(const char *v) {
234 assert(v);
235
44d8db9e 236 if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
85261803 237 return 1;
44d8db9e 238 else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
85261803
LP
239 return 0;
240
241 return -EINVAL;
242}
243
3ba686c1
LP
244int parse_pid(const char *s, pid_t* ret_pid) {
245 unsigned long ul;
246 pid_t pid;
247 int r;
248
249 assert(s);
250 assert(ret_pid);
251
252 if ((r = safe_atolu(s, &ul)) < 0)
253 return r;
254
255 pid = (pid_t) ul;
256
257 if ((unsigned long) pid != ul)
258 return -ERANGE;
259
260 if (pid <= 0)
261 return -ERANGE;
262
263 *ret_pid = pid;
264 return 0;
265}
266
85261803
LP
267int safe_atou(const char *s, unsigned *ret_u) {
268 char *x = NULL;
034c6ed7 269 unsigned long l;
85261803
LP
270
271 assert(s);
272 assert(ret_u);
273
274 errno = 0;
275 l = strtoul(s, &x, 0);
276
277 if (!x || *x || errno)
278 return errno ? -errno : -EINVAL;
279
034c6ed7 280 if ((unsigned long) (unsigned) l != l)
85261803
LP
281 return -ERANGE;
282
283 *ret_u = (unsigned) l;
284 return 0;
285}
286
287int safe_atoi(const char *s, int *ret_i) {
288 char *x = NULL;
034c6ed7 289 long l;
85261803
LP
290
291 assert(s);
292 assert(ret_i);
293
294 errno = 0;
295 l = strtol(s, &x, 0);
296
297 if (!x || *x || errno)
298 return errno ? -errno : -EINVAL;
299
034c6ed7 300 if ((long) (int) l != l)
85261803
LP
301 return -ERANGE;
302
034c6ed7
LP
303 *ret_i = (int) l;
304 return 0;
305}
306
307int safe_atolu(const char *s, long unsigned *ret_lu) {
308 char *x = NULL;
309 unsigned long l;
310
311 assert(s);
312 assert(ret_lu);
313
314 errno = 0;
315 l = strtoul(s, &x, 0);
316
317 if (!x || *x || errno)
318 return errno ? -errno : -EINVAL;
319
320 *ret_lu = l;
321 return 0;
322}
323
324int safe_atoli(const char *s, long int *ret_li) {
325 char *x = NULL;
326 long l;
327
328 assert(s);
329 assert(ret_li);
330
331 errno = 0;
332 l = strtol(s, &x, 0);
333
334 if (!x || *x || errno)
335 return errno ? -errno : -EINVAL;
336
337 *ret_li = l;
338 return 0;
339}
340
341int safe_atollu(const char *s, long long unsigned *ret_llu) {
342 char *x = NULL;
343 unsigned long long l;
344
345 assert(s);
346 assert(ret_llu);
347
348 errno = 0;
349 l = strtoull(s, &x, 0);
350
351 if (!x || *x || errno)
352 return errno ? -errno : -EINVAL;
353
354 *ret_llu = l;
355 return 0;
356}
357
358int safe_atolli(const char *s, long long int *ret_lli) {
359 char *x = NULL;
360 long long l;
361
362 assert(s);
363 assert(ret_lli);
364
365 errno = 0;
366 l = strtoll(s, &x, 0);
367
368 if (!x || *x || errno)
369 return errno ? -errno : -EINVAL;
370
371 *ret_lli = l;
85261803
LP
372 return 0;
373}
a41e8209 374
a41e8209 375/* Split a string into words. */
65d2ebdc 376char *split(const char *c, size_t *l, const char *separator, char **state) {
a41e8209
LP
377 char *current;
378
379 current = *state ? *state : (char*) c;
380
381 if (!*current || *c == 0)
382 return NULL;
383
65d2ebdc
LP
384 current += strspn(current, separator);
385 *l = strcspn(current, separator);
82919e3d
LP
386 *state = current+*l;
387
388 return (char*) current;
389}
390
034c6ed7
LP
391/* Split a string into words, but consider strings enclosed in '' and
392 * "" as words even if they include spaces. */
393char *split_quoted(const char *c, size_t *l, char **state) {
394 char *current;
395
396 current = *state ? *state : (char*) c;
397
398 if (!*current || *c == 0)
399 return NULL;
400
401 current += strspn(current, WHITESPACE);
402
403 if (*current == '\'') {
404 current ++;
405 *l = strcspn(current, "'");
406 *state = current+*l;
407
408 if (**state == '\'')
409 (*state)++;
410 } else if (*current == '\"') {
411 current ++;
b858b600 412 *l = strcspn(current, "\"");
034c6ed7
LP
413 *state = current+*l;
414
415 if (**state == '\"')
416 (*state)++;
417 } else {
418 *l = strcspn(current, WHITESPACE);
419 *state = current+*l;
420 }
421
44d8db9e
LP
422 /* FIXME: Cannot deal with strings that have spaces AND ticks
423 * in them */
424
034c6ed7
LP
425 return (char*) current;
426}
427
65d2ebdc
LP
428char **split_path_and_make_absolute(const char *p) {
429 char **l;
430 assert(p);
431
432 if (!(l = strv_split(p, ":")))
433 return NULL;
434
435 if (!strv_path_make_absolute_cwd(l)) {
436 strv_free(l);
437 return NULL;
438 }
439
440 return l;
441}
442
034c6ed7
LP
443int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
444 int r;
445 FILE *f;
446 char fn[132], line[256], *p;
447 long long unsigned ppid;
448
449 assert(pid >= 0);
450 assert(_ppid);
451
452 assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%llu/stat", (unsigned long long) pid) < (int) (sizeof(fn)-1));
453 fn[sizeof(fn)-1] = 0;
454
455 if (!(f = fopen(fn, "r")))
456 return -errno;
457
458 if (!(fgets(line, sizeof(line), f))) {
459 r = -errno;
460 fclose(f);
461 return r;
462 }
463
464 fclose(f);
465
466 /* Let's skip the pid and comm fields. The latter is enclosed
467 * in () but does not escape any () in its value, so let's
468 * skip over it manually */
469
470 if (!(p = strrchr(line, ')')))
471 return -EIO;
472
473 p++;
474
475 if (sscanf(p, " "
476 "%*c " /* state */
477 "%llu ", /* ppid */
478 &ppid) != 1)
479 return -EIO;
480
481 if ((long long unsigned) (pid_t) ppid != ppid)
482 return -ERANGE;
483
484 *_ppid = (pid_t) ppid;
485
486 return 0;
487}
488
489int write_one_line_file(const char *fn, const char *line) {
490 FILE *f;
491 int r;
492
493 assert(fn);
494 assert(line);
495
496 if (!(f = fopen(fn, "we")))
497 return -errno;
498
499 if (fputs(line, f) < 0) {
500 r = -errno;
501 goto finish;
502 }
503
504 r = 0;
505finish:
506 fclose(f);
507 return r;
508}
509
510int read_one_line_file(const char *fn, char **line) {
511 FILE *f;
512 int r;
11316633 513 char t[2048], *c;
034c6ed7
LP
514
515 assert(fn);
516 assert(line);
517
518 if (!(f = fopen(fn, "re")))
519 return -errno;
520
521 if (!(fgets(t, sizeof(t), f))) {
522 r = -errno;
523 goto finish;
524 }
525
526 if (!(c = strdup(t))) {
527 r = -ENOMEM;
528 goto finish;
529 }
530
531 *line = c;
532 r = 0;
533
534finish:
535 fclose(f);
536 return r;
537}
44d8db9e 538
7072ced8
LP
539char *truncate_nl(char *s) {
540 assert(s);
541
542 s[strcspn(s, NEWLINE)] = 0;
543 return s;
544}
545
546int get_process_name(pid_t pid, char **name) {
547 char *p;
548 int r;
549
550 assert(pid >= 1);
551 assert(name);
552
553 if (asprintf(&p, "/proc/%llu/comm", (unsigned long long) pid) < 0)
554 return -ENOMEM;
555
556 r = read_one_line_file(p, name);
557 free(p);
558
559 if (r < 0)
560 return r;
561
562 truncate_nl(*name);
563 return 0;
564}
565
44d8db9e
LP
566char *strappend(const char *s, const char *suffix) {
567 size_t a, b;
568 char *r;
569
570 assert(s);
571 assert(suffix);
572
573 a = strlen(s);
574 b = strlen(suffix);
575
576 if (!(r = new(char, a+b+1)))
577 return NULL;
578
579 memcpy(r, s, a);
580 memcpy(r+a, suffix, b);
581 r[a+b] = 0;
582
583 return r;
584}
87f0e418
LP
585
586int readlink_malloc(const char *p, char **r) {
587 size_t l = 100;
588
589 assert(p);
590 assert(r);
591
592 for (;;) {
593 char *c;
594 ssize_t n;
595
596 if (!(c = new(char, l)))
597 return -ENOMEM;
598
599 if ((n = readlink(p, c, l-1)) < 0) {
600 int ret = -errno;
601 free(c);
602 return ret;
603 }
604
605 if ((size_t) n < l-1) {
606 c[n] = 0;
607 *r = c;
608 return 0;
609 }
610
611 free(c);
612 l *= 2;
613 }
614}
615
2c7108c4
LP
616int readlink_and_make_absolute(const char *p, char **r) {
617 char *target, *k;
618 int j;
619
620 assert(p);
621 assert(r);
622
623 if ((j = readlink_malloc(p, &target)) < 0)
624 return j;
625
626 k = file_in_same_dir(p, target);
627 free(target);
628
629 if (!k)
630 return -ENOMEM;
631
632 *r = k;
633 return 0;
634}
635
87f0e418
LP
636char *file_name_from_path(const char *p) {
637 char *r;
638
639 assert(p);
640
641 if ((r = strrchr(p, '/')))
642 return r + 1;
643
644 return (char*) p;
645}
0301abf4
LP
646
647bool path_is_absolute(const char *p) {
648 assert(p);
649
650 return p[0] == '/';
651}
652
653bool is_path(const char *p) {
654
655 return !!strchr(p, '/');
656}
657
658char *path_make_absolute(const char *p, const char *prefix) {
659 char *r;
660
661 assert(p);
662
65d2ebdc
LP
663 /* Makes every item in the list an absolute path by prepending
664 * the prefix, if specified and necessary */
665
0301abf4
LP
666 if (path_is_absolute(p) || !prefix)
667 return strdup(p);
668
669 if (asprintf(&r, "%s/%s", prefix, p) < 0)
670 return NULL;
671
672 return r;
673}
2a987ee8 674
65d2ebdc
LP
675char *path_make_absolute_cwd(const char *p) {
676 char *cwd, *r;
677
678 assert(p);
679
680 /* Similar to path_make_absolute(), but prefixes with the
681 * current working directory. */
682
683 if (path_is_absolute(p))
684 return strdup(p);
685
686 if (!(cwd = get_current_dir_name()))
687 return NULL;
688
689 r = path_make_absolute(p, cwd);
690 free(cwd);
691
692 return r;
693}
694
695char **strv_path_make_absolute_cwd(char **l) {
696 char **s;
697
698 /* Goes through every item in the string list and makes it
699 * absolute. This works in place and won't rollback any
700 * changes on failure. */
701
702 STRV_FOREACH(s, l) {
703 char *t;
704
705 if (!(t = path_make_absolute_cwd(*s)))
706 return NULL;
707
708 free(*s);
709 *s = t;
710 }
711
712 return l;
713}
714
c3f6d675
LP
715char **strv_path_canonicalize(char **l) {
716 char **s;
717 unsigned k = 0;
718 bool enomem = false;
719
720 if (strv_isempty(l))
721 return l;
722
723 /* Goes through every item in the string list and canonicalize
724 * the path. This works in place and won't rollback any
725 * changes on failure. */
726
727 STRV_FOREACH(s, l) {
728 char *t, *u;
729
730 t = path_make_absolute_cwd(*s);
731 free(*s);
732
733 if (!t) {
734 enomem = true;
735 continue;
736 }
737
738 errno = 0;
739 u = canonicalize_file_name(t);
740 free(t);
741
742 if (!u) {
743 if (errno == ENOMEM || !errno)
744 enomem = true;
745
746 continue;
747 }
748
749 l[k++] = u;
750 }
751
752 l[k] = NULL;
753
754 if (enomem)
755 return NULL;
756
757 return l;
758}
759
2a987ee8
LP
760int reset_all_signal_handlers(void) {
761 int sig;
762
763 for (sig = 1; sig < _NSIG; sig++) {
764 struct sigaction sa;
765
766 if (sig == SIGKILL || sig == SIGSTOP)
767 continue;
768
769 zero(sa);
770 sa.sa_handler = SIG_DFL;
431c32bf 771 sa.sa_flags = SA_RESTART;
2a987ee8
LP
772
773 /* On Linux the first two RT signals are reserved by
774 * glibc, and sigaction() will return EINVAL for them. */
775 if ((sigaction(sig, &sa, NULL) < 0))
776 if (errno != EINVAL)
777 return -errno;
778 }
779
8e274523 780 return 0;
2a987ee8 781}
4a72ff34
LP
782
783char *strstrip(char *s) {
784 char *e, *l = NULL;
785
786 /* Drops trailing whitespace. Modifies the string in
787 * place. Returns pointer to first non-space character */
788
789 s += strspn(s, WHITESPACE);
790
791 for (e = s; *e; e++)
792 if (!strchr(WHITESPACE, *e))
793 l = e;
794
795 if (l)
796 *(l+1) = 0;
797 else
798 *s = 0;
799
800 return s;
4a72ff34
LP
801}
802
ee9b5e01
LP
803char *delete_chars(char *s, const char *bad) {
804 char *f, *t;
805
806 /* Drops all whitespace, regardless where in the string */
807
808 for (f = s, t = s; *f; f++) {
809 if (strchr(bad, *f))
810 continue;
811
812 *(t++) = *f;
813 }
814
815 *t = 0;
816
817 return s;
818}
819
4a72ff34
LP
820char *file_in_same_dir(const char *path, const char *filename) {
821 char *e, *r;
822 size_t k;
823
824 assert(path);
825 assert(filename);
826
827 /* This removes the last component of path and appends
828 * filename, unless the latter is absolute anyway or the
829 * former isn't */
830
831 if (path_is_absolute(filename))
832 return strdup(filename);
833
834 if (!(e = strrchr(path, '/')))
835 return strdup(filename);
836
837 k = strlen(filename);
838 if (!(r = new(char, e-path+1+k+1)))
839 return NULL;
840
841 memcpy(r, path, e-path+1);
842 memcpy(r+(e-path)+1, filename, k+1);
843
844 return r;
845}
fb624d04 846
a9f5d454
LP
847int mkdir_parents(const char *path, mode_t mode) {
848 const char *p, *e;
849
850 assert(path);
851
852 /* Creates every parent directory in the path except the last
853 * component. */
854
855 p = path + strspn(path, "/");
856 for (;;) {
857 int r;
858 char *t;
859
860 e = p + strcspn(p, "/");
861 p = e + strspn(e, "/");
862
863 /* Is this the last component? If so, then we're
864 * done */
865 if (*p == 0)
866 return 0;
867
868 if (!(t = strndup(path, e - path)))
869 return -ENOMEM;
870
871 r = mkdir(t, mode);
872
873 free(t);
874
875 if (r < 0 && errno != EEXIST)
876 return -errno;
877 }
878}
879
bbd67135
LP
880int mkdir_p(const char *path, mode_t mode) {
881 int r;
882
883 /* Like mkdir -p */
884
885 if ((r = mkdir_parents(path, mode)) < 0)
886 return r;
887
888 if (mkdir(path, mode) < 0)
889 return -errno;
890
891 return 0;
892}
893
fb624d04
LP
894char hexchar(int x) {
895 static const char table[16] = "0123456789abcdef";
896
897 return table[x & 15];
898}
4fe88d28
LP
899
900int unhexchar(char c) {
901
902 if (c >= '0' && c <= '9')
903 return c - '0';
904
905 if (c >= 'a' && c <= 'f')
ea430986 906 return c - 'a' + 10;
4fe88d28
LP
907
908 if (c >= 'A' && c <= 'F')
ea430986 909 return c - 'A' + 10;
4fe88d28
LP
910
911 return -1;
912}
913
914char octchar(int x) {
915 return '0' + (x & 7);
916}
917
918int unoctchar(char c) {
919
920 if (c >= '0' && c <= '7')
921 return c - '0';
922
923 return -1;
924}
925
5af98f82
LP
926char decchar(int x) {
927 return '0' + (x % 10);
928}
929
930int undecchar(char c) {
931
932 if (c >= '0' && c <= '9')
933 return c - '0';
934
935 return -1;
936}
937
4fe88d28
LP
938char *cescape(const char *s) {
939 char *r, *t;
940 const char *f;
941
942 assert(s);
943
944 /* Does C style string escaping. */
945
946 if (!(r = new(char, strlen(s)*4 + 1)))
947 return NULL;
948
949 for (f = s, t = r; *f; f++)
950
951 switch (*f) {
952
953 case '\a':
954 *(t++) = '\\';
955 *(t++) = 'a';
956 break;
957 case '\b':
958 *(t++) = '\\';
959 *(t++) = 'b';
960 break;
961 case '\f':
962 *(t++) = '\\';
963 *(t++) = 'f';
964 break;
965 case '\n':
966 *(t++) = '\\';
967 *(t++) = 'n';
968 break;
969 case '\r':
970 *(t++) = '\\';
971 *(t++) = 'r';
972 break;
973 case '\t':
974 *(t++) = '\\';
975 *(t++) = 't';
976 break;
977 case '\v':
978 *(t++) = '\\';
979 *(t++) = 'v';
980 break;
981 case '\\':
982 *(t++) = '\\';
983 *(t++) = '\\';
984 break;
985 case '"':
986 *(t++) = '\\';
987 *(t++) = '"';
988 break;
989 case '\'':
990 *(t++) = '\\';
991 *(t++) = '\'';
992 break;
993
994 default:
995 /* For special chars we prefer octal over
996 * hexadecimal encoding, simply because glib's
997 * g_strescape() does the same */
998 if ((*f < ' ') || (*f >= 127)) {
999 *(t++) = '\\';
1000 *(t++) = octchar((unsigned char) *f >> 6);
1001 *(t++) = octchar((unsigned char) *f >> 3);
1002 *(t++) = octchar((unsigned char) *f);
1003 } else
1004 *(t++) = *f;
1005 break;
1006 }
1007
1008 *t = 0;
1009
1010 return r;
1011}
1012
1013char *cunescape(const char *s) {
1014 char *r, *t;
1015 const char *f;
1016
1017 assert(s);
1018
1019 /* Undoes C style string escaping */
1020
1021 if (!(r = new(char, strlen(s)+1)))
1022 return r;
1023
1024 for (f = s, t = r; *f; f++) {
1025
1026 if (*f != '\\') {
1027 *(t++) = *f;
1028 continue;
1029 }
1030
1031 f++;
1032
1033 switch (*f) {
1034
1035 case 'a':
1036 *(t++) = '\a';
1037 break;
1038 case 'b':
1039 *(t++) = '\b';
1040 break;
1041 case 'f':
1042 *(t++) = '\f';
1043 break;
1044 case 'n':
1045 *(t++) = '\n';
1046 break;
1047 case 'r':
1048 *(t++) = '\r';
1049 break;
1050 case 't':
1051 *(t++) = '\t';
1052 break;
1053 case 'v':
1054 *(t++) = '\v';
1055 break;
1056 case '\\':
1057 *(t++) = '\\';
1058 break;
1059 case '"':
1060 *(t++) = '"';
1061 break;
1062 case '\'':
1063 *(t++) = '\'';
1064 break;
1065
1066 case 'x': {
1067 /* hexadecimal encoding */
1068 int a, b;
1069
1070 if ((a = unhexchar(f[1])) < 0 ||
1071 (b = unhexchar(f[2])) < 0) {
1072 /* Invalid escape code, let's take it literal then */
1073 *(t++) = '\\';
1074 *(t++) = 'x';
1075 } else {
1076 *(t++) = (char) ((a << 4) | b);
1077 f += 2;
1078 }
1079
1080 break;
1081 }
1082
1083 case '0':
1084 case '1':
1085 case '2':
1086 case '3':
1087 case '4':
1088 case '5':
1089 case '6':
1090 case '7': {
1091 /* octal encoding */
1092 int a, b, c;
1093
1094 if ((a = unoctchar(f[0])) < 0 ||
1095 (b = unoctchar(f[1])) < 0 ||
1096 (c = unoctchar(f[2])) < 0) {
1097 /* Invalid escape code, let's take it literal then */
1098 *(t++) = '\\';
1099 *(t++) = f[0];
1100 } else {
1101 *(t++) = (char) ((a << 6) | (b << 3) | c);
1102 f += 2;
1103 }
1104
1105 break;
1106 }
1107
1108 case 0:
1109 /* premature end of string.*/
1110 *(t++) = '\\';
1111 goto finish;
1112
1113 default:
1114 /* Invalid escape code, let's take it literal then */
1115 *(t++) = '\\';
1116 *(t++) = 'f';
1117 break;
1118 }
1119 }
1120
1121finish:
1122 *t = 0;
1123 return r;
1124}
1125
1126
1127char *xescape(const char *s, const char *bad) {
1128 char *r, *t;
1129 const char *f;
1130
1131 /* Escapes all chars in bad, in addition to \ and all special
1132 * chars, in \xFF style escaping. May be reversed with
1133 * cunescape. */
1134
1135 if (!(r = new(char, strlen(s)*4+1)))
1136 return NULL;
1137
1138 for (f = s, t = r; *f; f++) {
1139
b866264a
LP
1140 if ((*f < ' ') || (*f >= 127) ||
1141 (*f == '\\') || strchr(bad, *f)) {
4fe88d28
LP
1142 *(t++) = '\\';
1143 *(t++) = 'x';
1144 *(t++) = hexchar(*f >> 4);
1145 *(t++) = hexchar(*f);
1146 } else
1147 *(t++) = *f;
1148 }
1149
1150 *t = 0;
1151
1152 return r;
1153}
1154
ea430986 1155char *bus_path_escape(const char *s) {
ea430986
LP
1156 char *r, *t;
1157 const char *f;
1158
47be870b
LP
1159 assert(s);
1160
ea430986
LP
1161 /* Escapes all chars that D-Bus' object path cannot deal
1162 * with. Can be reverse with bus_path_unescape() */
1163
1164 if (!(r = new(char, strlen(s)*3+1)))
1165 return NULL;
1166
1167 for (f = s, t = r; *f; f++) {
1168
1169 if (!(*f >= 'A' && *f <= 'Z') &&
1170 !(*f >= 'a' && *f <= 'z') &&
1171 !(*f >= '0' && *f <= '9')) {
1172 *(t++) = '_';
1173 *(t++) = hexchar(*f >> 4);
1174 *(t++) = hexchar(*f);
1175 } else
1176 *(t++) = *f;
1177 }
1178
1179 *t = 0;
1180
1181 return r;
1182}
1183
9e2f7c11 1184char *bus_path_unescape(const char *f) {
ea430986 1185 char *r, *t;
ea430986 1186
9e2f7c11 1187 assert(f);
47be870b 1188
9e2f7c11 1189 if (!(r = strdup(f)))
ea430986
LP
1190 return NULL;
1191
9e2f7c11 1192 for (t = r; *f; f++) {
ea430986
LP
1193
1194 if (*f == '_') {
1195 int a, b;
1196
1197 if ((a = unhexchar(f[1])) < 0 ||
1198 (b = unhexchar(f[2])) < 0) {
1199 /* Invalid escape code, let's take it literal then */
1200 *(t++) = '_';
1201 } else {
1202 *(t++) = (char) ((a << 4) | b);
1203 f += 2;
1204 }
1205 } else
1206 *(t++) = *f;
1207 }
1208
1209 *t = 0;
1210
1211 return r;
1212}
1213
4fe88d28
LP
1214char *path_kill_slashes(char *path) {
1215 char *f, *t;
1216 bool slash = false;
1217
1218 /* Removes redundant inner and trailing slashes. Modifies the
1219 * passed string in-place.
1220 *
1221 * ///foo///bar/ becomes /foo/bar
1222 */
1223
1224 for (f = path, t = path; *f; f++) {
1225
1226 if (*f == '/') {
1227 slash = true;
1228 continue;
1229 }
1230
1231 if (slash) {
1232 slash = false;
1233 *(t++) = '/';
1234 }
1235
1236 *(t++) = *f;
1237 }
1238
1239 /* Special rule, if we are talking of the root directory, a
1240 trailing slash is good */
1241
1242 if (t == path && slash)
1243 *(t++) = '/';
1244
1245 *t = 0;
1246 return path;
1247}
1248
1249bool path_startswith(const char *path, const char *prefix) {
1250 assert(path);
1251 assert(prefix);
1252
1253 if ((path[0] == '/') != (prefix[0] == '/'))
1254 return false;
1255
1256 for (;;) {
1257 size_t a, b;
1258
1259 path += strspn(path, "/");
1260 prefix += strspn(prefix, "/");
1261
1262 if (*prefix == 0)
1263 return true;
1264
1265 if (*path == 0)
1266 return false;
1267
1268 a = strcspn(path, "/");
1269 b = strcspn(prefix, "/");
1270
1271 if (a != b)
1272 return false;
1273
1274 if (memcmp(path, prefix, a) != 0)
1275 return false;
1276
1277 path += a;
1278 prefix += b;
1279 }
1280}
1281
15ae422b
LP
1282bool path_equal(const char *a, const char *b) {
1283 assert(a);
1284 assert(b);
1285
1286 if ((a[0] == '/') != (b[0] == '/'))
1287 return false;
1288
1289 for (;;) {
1290 size_t j, k;
1291
1292 a += strspn(a, "/");
1293 b += strspn(b, "/");
1294
1295 if (*a == 0 && *b == 0)
1296 return true;
1297
1298 if (*a == 0 || *b == 0)
1299 return false;
1300
1301 j = strcspn(a, "/");
1302 k = strcspn(b, "/");
1303
1304 if (j != k)
1305 return false;
1306
1307 if (memcmp(a, b, j) != 0)
1308 return false;
1309
1310 a += j;
1311 b += k;
1312 }
1313}
1314
67d51650 1315char *ascii_strlower(char *t) {
4fe88d28
LP
1316 char *p;
1317
67d51650 1318 assert(t);
4fe88d28 1319
67d51650 1320 for (p = t; *p; p++)
4fe88d28
LP
1321 if (*p >= 'A' && *p <= 'Z')
1322 *p = *p - 'A' + 'a';
1323
67d51650 1324 return t;
4fe88d28 1325}
1dccbe19 1326
c85dc17b
LP
1327bool ignore_file(const char *filename) {
1328 assert(filename);
1329
1330 return
1331 filename[0] == '.' ||
6c78be3c 1332 streq(filename, "lost+found") ||
c85dc17b
LP
1333 endswith(filename, "~") ||
1334 endswith(filename, ".rpmnew") ||
1335 endswith(filename, ".rpmsave") ||
1336 endswith(filename, ".rpmorig") ||
1337 endswith(filename, ".dpkg-old") ||
1338 endswith(filename, ".dpkg-new") ||
1339 endswith(filename, ".swp");
1340}
1341
3a0ecb08
LP
1342int fd_nonblock(int fd, bool nonblock) {
1343 int flags;
1344
1345 assert(fd >= 0);
1346
1347 if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
1348 return -errno;
1349
1350 if (nonblock)
1351 flags |= O_NONBLOCK;
1352 else
1353 flags &= ~O_NONBLOCK;
1354
1355 if (fcntl(fd, F_SETFL, flags) < 0)
1356 return -errno;
1357
1358 return 0;
1359}
1360
1361int fd_cloexec(int fd, bool cloexec) {
1362 int flags;
1363
1364 assert(fd >= 0);
1365
1366 if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
1367 return -errno;
1368
1369 if (cloexec)
1370 flags |= FD_CLOEXEC;
1371 else
1372 flags &= ~FD_CLOEXEC;
1373
1374 if (fcntl(fd, F_SETFD, flags) < 0)
1375 return -errno;
1376
1377 return 0;
1378}
1379
a0d40ac5
LP
1380int close_all_fds(const int except[], unsigned n_except) {
1381 DIR *d;
1382 struct dirent *de;
1383 int r = 0;
1384
1385 if (!(d = opendir("/proc/self/fd")))
1386 return -errno;
1387
1388 while ((de = readdir(d))) {
a7610064 1389 int fd = -1;
a0d40ac5 1390
a16e1123 1391 if (ignore_file(de->d_name))
a0d40ac5
LP
1392 continue;
1393
1394 if ((r = safe_atoi(de->d_name, &fd)) < 0)
1395 goto finish;
1396
1397 if (fd < 3)
1398 continue;
1399
1400 if (fd == dirfd(d))
1401 continue;
1402
1403 if (except) {
1404 bool found;
1405 unsigned i;
1406
1407 found = false;
1408 for (i = 0; i < n_except; i++)
1409 if (except[i] == fd) {
1410 found = true;
1411 break;
1412 }
1413
1414 if (found)
1415 continue;
1416 }
1417
2f357920
LP
1418 if ((r = close_nointr(fd)) < 0) {
1419 /* Valgrind has its own FD and doesn't want to have it closed */
1420 if (errno != EBADF)
1421 goto finish;
1422 }
a0d40ac5
LP
1423 }
1424
2f357920
LP
1425 r = 0;
1426
a0d40ac5
LP
1427finish:
1428 closedir(d);
1429 return r;
1430}
1431
db12775d
LP
1432bool chars_intersect(const char *a, const char *b) {
1433 const char *p;
1434
1435 /* Returns true if any of the chars in a are in b. */
1436 for (p = a; *p; p++)
1437 if (strchr(b, *p))
1438 return true;
1439
1440 return false;
1441}
1442
8b6c7120
LP
1443char *format_timestamp(char *buf, size_t l, usec_t t) {
1444 struct tm tm;
1445 time_t sec;
1446
1447 assert(buf);
1448 assert(l > 0);
1449
1450 if (t <= 0)
1451 return NULL;
1452
1453 sec = (time_t) t / USEC_PER_SEC;
1454
1455 if (strftime(buf, l, "%a, %d %b %Y %H:%M:%S %z", localtime_r(&sec, &tm)) <= 0)
1456 return NULL;
1457
1458 return buf;
1459}
1460
871d7de4
LP
1461char *format_timespan(char *buf, size_t l, usec_t t) {
1462 static const struct {
1463 const char *suffix;
1464 usec_t usec;
1465 } table[] = {
1466 { "w", USEC_PER_WEEK },
1467 { "d", USEC_PER_DAY },
1468 { "h", USEC_PER_HOUR },
1469 { "min", USEC_PER_MINUTE },
1470 { "s", USEC_PER_SEC },
1471 { "ms", USEC_PER_MSEC },
1472 { "us", 1 },
1473 };
1474
1475 unsigned i;
1476 char *p = buf;
1477
1478 assert(buf);
1479 assert(l > 0);
1480
1481 if (t == (usec_t) -1)
1482 return NULL;
1483
1484 /* The result of this function can be parsed with parse_usec */
1485
1486 for (i = 0; i < ELEMENTSOF(table); i++) {
1487 int k;
1488 size_t n;
1489
1490 if (t < table[i].usec)
1491 continue;
1492
1493 if (l <= 1)
1494 break;
1495
1496 k = snprintf(p, l, "%s%llu%s", p > buf ? " " : "", (unsigned long long) (t / table[i].usec), table[i].suffix);
1497 n = MIN((size_t) k, l);
1498
1499 l -= n;
1500 p += n;
1501
1502 t %= table[i].usec;
1503 }
1504
1505 *p = 0;
1506
1507 return buf;
1508}
1509
42856c10
LP
1510bool fstype_is_network(const char *fstype) {
1511 static const char * const table[] = {
1512 "cifs",
1513 "smbfs",
1514 "ncpfs",
1515 "nfs",
ca139f94
LP
1516 "nfs4",
1517 "gfs",
1518 "gfs2"
42856c10
LP
1519 };
1520
1521 unsigned i;
1522
1523 for (i = 0; i < ELEMENTSOF(table); i++)
1524 if (streq(table[i], fstype))
1525 return true;
1526
1527 return false;
1528}
1529
601f6a1e
LP
1530int chvt(int vt) {
1531 int fd, r = 0;
1532
1533 if ((fd = open("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0)
1534 return -errno;
1535
1536 if (vt < 0) {
1537 int tiocl[2] = {
1538 TIOCL_GETKMSGREDIRECT,
1539 0
1540 };
1541
1542 if (ioctl(fd, TIOCLINUX, tiocl) < 0)
1543 return -errno;
1544
1545 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
1546 }
1547
1548 if (ioctl(fd, VT_ACTIVATE, vt) < 0)
1549 r = -errno;
1550
a16e1123 1551 close_nointr_nofail(r);
601f6a1e
LP
1552 return r;
1553}
1554
80876c20
LP
1555int read_one_char(FILE *f, char *ret, bool *need_nl) {
1556 struct termios old_termios, new_termios;
1557 char c;
1558 char line[1024];
1559
1560 assert(f);
1561 assert(ret);
1562
1563 if (tcgetattr(fileno(f), &old_termios) >= 0) {
1564 new_termios = old_termios;
1565
1566 new_termios.c_lflag &= ~ICANON;
1567 new_termios.c_cc[VMIN] = 1;
1568 new_termios.c_cc[VTIME] = 0;
1569
1570 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
1571 size_t k;
1572
1573 k = fread(&c, 1, 1, f);
1574
1575 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
1576
1577 if (k <= 0)
1578 return -EIO;
1579
1580 if (need_nl)
1581 *need_nl = c != '\n';
1582
1583 *ret = c;
1584 return 0;
1585 }
1586 }
1587
1588 if (!(fgets(line, sizeof(line), f)))
1589 return -EIO;
1590
1591 truncate_nl(line);
1592
1593 if (strlen(line) != 1)
1594 return -EBADMSG;
1595
1596 if (need_nl)
1597 *need_nl = false;
1598
1599 *ret = line[0];
1600 return 0;
1601}
1602
1603int ask(char *ret, const char *replies, const char *text, ...) {
1604 assert(ret);
1605 assert(replies);
1606 assert(text);
1607
1608 for (;;) {
1609 va_list ap;
1610 char c;
1611 int r;
1612 bool need_nl = true;
1613
b1b2dc0c
LP
1614 fputs("\x1B[1m", stdout);
1615
80876c20
LP
1616 va_start(ap, text);
1617 vprintf(text, ap);
1618 va_end(ap);
1619
b1b2dc0c
LP
1620 fputs("\x1B[0m", stdout);
1621
80876c20
LP
1622 fflush(stdout);
1623
1624 if ((r = read_one_char(stdin, &c, &need_nl)) < 0) {
1625
1626 if (r == -EBADMSG) {
1627 puts("Bad input, please try again.");
1628 continue;
1629 }
1630
1631 putchar('\n');
1632 return r;
1633 }
1634
1635 if (need_nl)
1636 putchar('\n');
1637
1638 if (strchr(replies, c)) {
1639 *ret = c;
1640 return 0;
1641 }
1642
1643 puts("Read unexpected character, please try again.");
1644 }
1645}
1646
1647int reset_terminal(int fd) {
1648 struct termios termios;
1649 int r = 0;
1650
1651 assert(fd >= 0);
1652
aaf694ca 1653 /* Set terminal to some sane defaults */
80876c20
LP
1654
1655 if (tcgetattr(fd, &termios) < 0) {
1656 r = -errno;
1657 goto finish;
1658 }
1659
aaf694ca
LP
1660 /* We only reset the stuff that matters to the software. How
1661 * hardware is set up we don't touch assuming that somebody
1662 * else will do that for us */
1663
1664 termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
80876c20
LP
1665 termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
1666 termios.c_oflag |= ONLCR;
1667 termios.c_cflag |= CREAD;
1668 termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
1669
1670 termios.c_cc[VINTR] = 03; /* ^C */
1671 termios.c_cc[VQUIT] = 034; /* ^\ */
1672 termios.c_cc[VERASE] = 0177;
1673 termios.c_cc[VKILL] = 025; /* ^X */
1674 termios.c_cc[VEOF] = 04; /* ^D */
1675 termios.c_cc[VSTART] = 021; /* ^Q */
1676 termios.c_cc[VSTOP] = 023; /* ^S */
1677 termios.c_cc[VSUSP] = 032; /* ^Z */
1678 termios.c_cc[VLNEXT] = 026; /* ^V */
1679 termios.c_cc[VWERASE] = 027; /* ^W */
1680 termios.c_cc[VREPRINT] = 022; /* ^R */
aaf694ca
LP
1681 termios.c_cc[VEOL] = 0;
1682 termios.c_cc[VEOL2] = 0;
80876c20
LP
1683
1684 termios.c_cc[VTIME] = 0;
1685 termios.c_cc[VMIN] = 1;
1686
1687 if (tcsetattr(fd, TCSANOW, &termios) < 0)
1688 r = -errno;
1689
1690finish:
1691 /* Just in case, flush all crap out */
1692 tcflush(fd, TCIOFLUSH);
1693
1694 return r;
1695}
1696
1697int open_terminal(const char *name, int mode) {
1698 int fd, r;
1699
1700 if ((fd = open(name, mode)) < 0)
1701 return -errno;
1702
1703 if ((r = isatty(fd)) < 0) {
1704 close_nointr_nofail(fd);
1705 return -errno;
1706 }
1707
1708 if (!r) {
1709 close_nointr_nofail(fd);
1710 return -ENOTTY;
1711 }
1712
1713 return fd;
1714}
1715
1716int flush_fd(int fd) {
1717 struct pollfd pollfd;
1718
1719 zero(pollfd);
1720 pollfd.fd = fd;
1721 pollfd.events = POLLIN;
1722
1723 for (;;) {
1724 char buf[1024];
1725 ssize_t l;
1726 int r;
1727
1728 if ((r = poll(&pollfd, 1, 0)) < 0) {
1729
1730 if (errno == EINTR)
1731 continue;
1732
1733 return -errno;
1734 }
1735
1736 if (r == 0)
1737 return 0;
1738
1739 if ((l = read(fd, buf, sizeof(buf))) < 0) {
1740
1741 if (errno == EINTR)
1742 continue;
1743
1744 if (errno == EAGAIN)
1745 return 0;
1746
1747 return -errno;
1748 }
1749
1750 if (l <= 0)
1751 return 0;
1752 }
1753}
1754
21de3988 1755int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocstty_eperm) {
bab45044 1756 int fd = -1, notify = -1, r, wd = -1;
80876c20
LP
1757
1758 assert(name);
1759
1760 /* We use inotify to be notified when the tty is closed. We
1761 * create the watch before checking if we can actually acquire
1762 * it, so that we don't lose any event.
1763 *
1764 * Note: strictly speaking this actually watches for the
1765 * device being closed, it does *not* really watch whether a
1766 * tty loses its controlling process. However, unless some
1767 * rogue process uses TIOCNOTTY on /dev/tty *after* closing
1768 * its tty otherwise this will not become a problem. As long
1769 * as the administrator makes sure not configure any service
1770 * on the same tty as an untrusted user this should not be a
1771 * problem. (Which he probably should not do anyway.) */
1772
1773 if (!fail && !force) {
1774 if ((notify = inotify_init1(IN_CLOEXEC)) < 0) {
1775 r = -errno;
1776 goto fail;
1777 }
1778
1779 if ((wd = inotify_add_watch(notify, name, IN_CLOSE)) < 0) {
1780 r = -errno;
1781 goto fail;
1782 }
1783 }
1784
1785 for (;;) {
e3d1855b
LP
1786 if (notify >= 0)
1787 if ((r = flush_fd(notify)) < 0)
1788 goto fail;
80876c20
LP
1789
1790 /* We pass here O_NOCTTY only so that we can check the return
1791 * value TIOCSCTTY and have a reliable way to figure out if we
1792 * successfully became the controlling process of the tty */
1793 if ((fd = open_terminal(name, O_RDWR|O_NOCTTY)) < 0)
1794 return -errno;
1795
1796 /* First, try to get the tty */
21de3988
LP
1797 r = ioctl(fd, TIOCSCTTY, force);
1798
1799 /* Sometimes it makes sense to ignore TIOCSCTTY
1800 * returning EPERM, i.e. when very likely we already
1801 * are have this controlling terminal. */
1802 if (r < 0 && errno == EPERM && ignore_tiocstty_eperm)
1803 r = 0;
1804
1805 if (r < 0 && (force || fail || errno != EPERM)) {
80876c20
LP
1806 r = -errno;
1807 goto fail;
1808 }
1809
1810 if (r >= 0)
1811 break;
1812
1813 assert(!fail);
1814 assert(!force);
1815 assert(notify >= 0);
1816
1817 for (;;) {
1818 struct inotify_event e;
1819 ssize_t l;
1820
1821 if ((l = read(notify, &e, sizeof(e))) != sizeof(e)) {
1822
1823 if (l < 0) {
1824
1825 if (errno == EINTR)
1826 continue;
1827
1828 r = -errno;
1829 } else
1830 r = -EIO;
1831
1832 goto fail;
1833 }
1834
1835 if (e.wd != wd || !(e.mask & IN_CLOSE)) {
1836 r = -errno;
1837 goto fail;
1838 }
1839
1840 break;
1841 }
1842
1843 /* We close the tty fd here since if the old session
1844 * ended our handle will be dead. It's important that
1845 * we do this after sleeping, so that we don't enter
1846 * an endless loop. */
1847 close_nointr_nofail(fd);
1848 }
1849
1850 if (notify >= 0)
a16e1123 1851 close_nointr_nofail(notify);
80876c20
LP
1852
1853 if ((r = reset_terminal(fd)) < 0)
1854 log_warning("Failed to reset terminal: %s", strerror(-r));
1855
1856 return fd;
1857
1858fail:
1859 if (fd >= 0)
a16e1123 1860 close_nointr_nofail(fd);
80876c20
LP
1861
1862 if (notify >= 0)
a16e1123 1863 close_nointr_nofail(notify);
80876c20
LP
1864
1865 return r;
1866}
1867
1868int release_terminal(void) {
1869 int r = 0, fd;
57cd2192 1870 struct sigaction sa_old, sa_new;
80876c20 1871
57cd2192 1872 if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY)) < 0)
80876c20
LP
1873 return -errno;
1874
57cd2192
LP
1875 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
1876 * by our own TIOCNOTTY */
1877
1878 zero(sa_new);
1879 sa_new.sa_handler = SIG_IGN;
1880 sa_new.sa_flags = SA_RESTART;
1881 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
1882
80876c20
LP
1883 if (ioctl(fd, TIOCNOTTY) < 0)
1884 r = -errno;
1885
57cd2192
LP
1886 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
1887
80876c20
LP
1888 close_nointr_nofail(fd);
1889 return r;
1890}
1891
9a34ec5f
LP
1892int sigaction_many(const struct sigaction *sa, ...) {
1893 va_list ap;
1894 int r = 0, sig;
1895
1896 va_start(ap, sa);
1897 while ((sig = va_arg(ap, int)) > 0)
1898 if (sigaction(sig, sa, NULL) < 0)
1899 r = -errno;
1900 va_end(ap);
1901
1902 return r;
1903}
1904
1905int ignore_signals(int sig, ...) {
a337c6fc 1906 struct sigaction sa;
9a34ec5f
LP
1907 va_list ap;
1908 int r = 0;
a337c6fc
LP
1909
1910 zero(sa);
1911 sa.sa_handler = SIG_IGN;
1912 sa.sa_flags = SA_RESTART;
1913
9a34ec5f
LP
1914 if (sigaction(sig, &sa, NULL) < 0)
1915 r = -errno;
1916
1917 va_start(ap, sig);
1918 while ((sig = va_arg(ap, int)) > 0)
1919 if (sigaction(sig, &sa, NULL) < 0)
1920 r = -errno;
1921 va_end(ap);
1922
1923 return r;
1924}
1925
1926int default_signals(int sig, ...) {
1927 struct sigaction sa;
1928 va_list ap;
1929 int r = 0;
1930
1931 zero(sa);
1932 sa.sa_handler = SIG_DFL;
1933 sa.sa_flags = SA_RESTART;
1934
1935 if (sigaction(sig, &sa, NULL) < 0)
1936 r = -errno;
1937
1938 va_start(ap, sig);
1939 while ((sig = va_arg(ap, int)) > 0)
1940 if (sigaction(sig, &sa, NULL) < 0)
1941 r = -errno;
1942 va_end(ap);
1943
1944 return r;
a337c6fc
LP
1945}
1946
8d567588
LP
1947int close_pipe(int p[]) {
1948 int a = 0, b = 0;
1949
1950 assert(p);
1951
1952 if (p[0] >= 0) {
1953 a = close_nointr(p[0]);
1954 p[0] = -1;
1955 }
1956
1957 if (p[1] >= 0) {
1958 b = close_nointr(p[1]);
1959 p[1] = -1;
1960 }
1961
1962 return a < 0 ? a : b;
1963}
1964
1965ssize_t loop_read(int fd, void *buf, size_t nbytes) {
1966 uint8_t *p;
1967 ssize_t n = 0;
1968
1969 assert(fd >= 0);
1970 assert(buf);
1971
1972 p = buf;
1973
1974 while (nbytes > 0) {
1975 ssize_t k;
1976
1977 if ((k = read(fd, p, nbytes)) <= 0) {
1978
1979 if (errno == EINTR)
1980 continue;
1981
1982 if (errno == EAGAIN) {
1983 struct pollfd pollfd;
1984
1985 zero(pollfd);
1986 pollfd.fd = fd;
1987 pollfd.events = POLLIN;
1988
1989 if (poll(&pollfd, 1, -1) < 0) {
1990 if (errno == EINTR)
1991 continue;
1992
1993 return n > 0 ? n : -errno;
1994 }
1995
1996 if (pollfd.revents != POLLIN)
1997 return n > 0 ? n : -EIO;
1998
1999 continue;
2000 }
2001
2002 return n > 0 ? n : (k < 0 ? -errno : 0);
2003 }
2004
2005 p += k;
2006 nbytes -= k;
2007 n += k;
2008 }
2009
2010 return n;
2011}
2012
2013int path_is_mount_point(const char *t) {
2014 struct stat a, b;
2015 char *copy;
2016
2017 if (lstat(t, &a) < 0) {
2018
2019 if (errno == ENOENT)
2020 return 0;
2021
2022 return -errno;
2023 }
2024
2025 if (!(copy = strdup(t)))
2026 return -ENOMEM;
2027
2028 if (lstat(dirname(copy), &b) < 0) {
2029 free(copy);
2030 return -errno;
2031 }
2032
2033 free(copy);
2034
2035 return a.st_dev != b.st_dev;
2036}
2037
24a6e4a4
LP
2038int parse_usec(const char *t, usec_t *usec) {
2039 static const struct {
2040 const char *suffix;
2041 usec_t usec;
2042 } table[] = {
2043 { "sec", USEC_PER_SEC },
2044 { "s", USEC_PER_SEC },
2045 { "min", USEC_PER_MINUTE },
2046 { "hr", USEC_PER_HOUR },
2047 { "h", USEC_PER_HOUR },
2048 { "d", USEC_PER_DAY },
2049 { "w", USEC_PER_WEEK },
2050 { "msec", USEC_PER_MSEC },
2051 { "ms", USEC_PER_MSEC },
2052 { "m", USEC_PER_MINUTE },
2053 { "usec", 1ULL },
2054 { "us", 1ULL },
2055 { "", USEC_PER_SEC },
2056 };
2057
2058 const char *p;
2059 usec_t r = 0;
2060
2061 assert(t);
2062 assert(usec);
2063
2064 p = t;
2065 do {
2066 long long l;
2067 char *e;
2068 unsigned i;
2069
2070 errno = 0;
2071 l = strtoll(p, &e, 10);
2072
2073 if (errno != 0)
2074 return -errno;
2075
2076 if (l < 0)
2077 return -ERANGE;
2078
2079 if (e == p)
2080 return -EINVAL;
2081
2082 e += strspn(e, WHITESPACE);
2083
2084 for (i = 0; i < ELEMENTSOF(table); i++)
2085 if (startswith(e, table[i].suffix)) {
2086 r += (usec_t) l * table[i].usec;
2087 p = e + strlen(table[i].suffix);
2088 break;
2089 }
2090
2091 if (i >= ELEMENTSOF(table))
2092 return -EINVAL;
2093
2094 } while (*p != 0);
2095
2096 *usec = r;
2097
2098 return 0;
2099}
2100
843d2643
LP
2101int make_stdio(int fd) {
2102 int r, s, t;
2103
2104 assert(fd >= 0);
2105
2106 r = dup2(fd, STDIN_FILENO);
2107 s = dup2(fd, STDOUT_FILENO);
2108 t = dup2(fd, STDERR_FILENO);
2109
2110 if (fd >= 3)
2111 close_nointr_nofail(fd);
2112
2113 if (r < 0 || s < 0 || t < 0)
2114 return -errno;
2115
2116 return 0;
2117}
2118
cb8a8f78
LP
2119bool is_clean_exit(int code, int status) {
2120
2121 if (code == CLD_EXITED)
2122 return status == 0;
2123
2124 /* If a daemon does not implement handlers for some of the
2125 * signals that's not considered an unclean shutdown */
2126 if (code == CLD_KILLED)
2127 return
2128 status == SIGHUP ||
2129 status == SIGINT ||
2130 status == SIGTERM ||
2131 status == SIGPIPE;
2132
2133 return false;
2134}
2135
8407a5d0
LP
2136bool is_device_path(const char *path) {
2137
2138 /* Returns true on paths that refer to a device, either in
2139 * sysfs or in /dev */
2140
2141 return
2142 path_startswith(path, "/dev/") ||
2143 path_startswith(path, "/sys/");
2144}
2145
01f78473
LP
2146int dir_is_empty(const char *path) {
2147 DIR *d;
2148 int r;
2149 struct dirent buf, *de;
2150
2151 if (!(d = opendir(path)))
2152 return -errno;
2153
2154 for (;;) {
2155 if ((r = readdir_r(d, &buf, &de)) > 0) {
2156 r = -r;
2157 break;
2158 }
2159
2160 if (!de) {
2161 r = 1;
2162 break;
2163 }
2164
2165 if (!ignore_file(de->d_name)) {
2166 r = 0;
2167 break;
2168 }
2169 }
2170
2171 closedir(d);
2172 return r;
2173}
2174
d3782d60
LP
2175unsigned long long random_ull(void) {
2176 int fd;
2177 uint64_t ull;
2178 ssize_t r;
2179
2180 if ((fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0)
2181 goto fallback;
2182
2183 r = loop_read(fd, &ull, sizeof(ull));
2184 close_nointr_nofail(fd);
2185
2186 if (r != sizeof(ull))
2187 goto fallback;
2188
2189 return ull;
2190
2191fallback:
2192 return random() * RAND_MAX + random();
2193}
2194
5b6319dc
LP
2195void rename_process(const char name[8]) {
2196 assert(name);
2197
2198 prctl(PR_SET_NAME, name);
2199
2200 /* This is a like a poor man's setproctitle(). The string
2201 * passed should fit in 7 chars (i.e. the length of
2202 * "systemd") */
2203
2204 if (program_invocation_name)
2205 strncpy(program_invocation_name, name, strlen(program_invocation_name));
2206}
2207
1dccbe19
LP
2208static const char *const ioprio_class_table[] = {
2209 [IOPRIO_CLASS_NONE] = "none",
2210 [IOPRIO_CLASS_RT] = "realtime",
2211 [IOPRIO_CLASS_BE] = "best-effort",
2212 [IOPRIO_CLASS_IDLE] = "idle"
2213};
2214
2215DEFINE_STRING_TABLE_LOOKUP(ioprio_class, int);
2216
2217static const char *const sigchld_code_table[] = {
2218 [CLD_EXITED] = "exited",
2219 [CLD_KILLED] = "killed",
2220 [CLD_DUMPED] = "dumped",
2221 [CLD_TRAPPED] = "trapped",
2222 [CLD_STOPPED] = "stopped",
2223 [CLD_CONTINUED] = "continued",
2224};
2225
2226DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
2227
2228static const char *const log_facility_table[LOG_NFACILITIES] = {
2229 [LOG_FAC(LOG_KERN)] = "kern",
2230 [LOG_FAC(LOG_USER)] = "user",
2231 [LOG_FAC(LOG_MAIL)] = "mail",
2232 [LOG_FAC(LOG_DAEMON)] = "daemon",
2233 [LOG_FAC(LOG_AUTH)] = "auth",
2234 [LOG_FAC(LOG_SYSLOG)] = "syslog",
2235 [LOG_FAC(LOG_LPR)] = "lpr",
2236 [LOG_FAC(LOG_NEWS)] = "news",
2237 [LOG_FAC(LOG_UUCP)] = "uucp",
2238 [LOG_FAC(LOG_CRON)] = "cron",
2239 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
2240 [LOG_FAC(LOG_FTP)] = "ftp",
2241 [LOG_FAC(LOG_LOCAL0)] = "local0",
2242 [LOG_FAC(LOG_LOCAL1)] = "local1",
2243 [LOG_FAC(LOG_LOCAL2)] = "local2",
2244 [LOG_FAC(LOG_LOCAL3)] = "local3",
2245 [LOG_FAC(LOG_LOCAL4)] = "local4",
2246 [LOG_FAC(LOG_LOCAL5)] = "local5",
2247 [LOG_FAC(LOG_LOCAL6)] = "local6",
2248 [LOG_FAC(LOG_LOCAL7)] = "local7"
2249};
2250
2251DEFINE_STRING_TABLE_LOOKUP(log_facility, int);
2252
2253static const char *const log_level_table[] = {
2254 [LOG_EMERG] = "emerg",
2255 [LOG_ALERT] = "alert",
2256 [LOG_CRIT] = "crit",
2257 [LOG_ERR] = "err",
2258 [LOG_WARNING] = "warning",
2259 [LOG_NOTICE] = "notice",
2260 [LOG_INFO] = "info",
2261 [LOG_DEBUG] = "debug"
2262};
2263
2264DEFINE_STRING_TABLE_LOOKUP(log_level, int);
2265
2266static const char* const sched_policy_table[] = {
2267 [SCHED_OTHER] = "other",
2268 [SCHED_BATCH] = "batch",
2269 [SCHED_IDLE] = "idle",
2270 [SCHED_FIFO] = "fifo",
2271 [SCHED_RR] = "rr"
2272};
2273
2274DEFINE_STRING_TABLE_LOOKUP(sched_policy, int);
2275
2276static const char* const rlimit_table[] = {
2277 [RLIMIT_CPU] = "LimitCPU",
2278 [RLIMIT_FSIZE] = "LimitFSIZE",
2279 [RLIMIT_DATA] = "LimitDATA",
2280 [RLIMIT_STACK] = "LimitSTACK",
2281 [RLIMIT_CORE] = "LimitCORE",
2282 [RLIMIT_RSS] = "LimitRSS",
2283 [RLIMIT_NOFILE] = "LimitNOFILE",
2284 [RLIMIT_AS] = "LimitAS",
2285 [RLIMIT_NPROC] = "LimitNPROC",
2286 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
2287 [RLIMIT_LOCKS] = "LimitLOCKS",
2288 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
2289 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
2290 [RLIMIT_NICE] = "LimitNICE",
2291 [RLIMIT_RTPRIO] = "LimitRTPRIO",
2292 [RLIMIT_RTTIME] = "LimitRTTIME"
2293};
2294
2295DEFINE_STRING_TABLE_LOOKUP(rlimit, int);