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