1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
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 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
31 #include <sys/resource.h>
32 #include <linux/sched.h>
33 #include <sys/types.h>
37 #include <sys/ioctl.h>
39 #include <linux/tiocl.h>
42 #include <sys/inotify.h>
45 #include <sys/prctl.h>
46 #include <sys/utsname.h>
48 #include <netinet/ip.h>
57 #include <linux/magic.h>
61 #include <sys/personality.h>
65 #ifdef HAVE_SYS_AUXV_H
76 #include "path-util.h"
77 #include "exit-status.h"
81 #include "device-nodes.h"
89 char **saved_argv = NULL;
91 static volatile unsigned cached_columns = 0;
92 static volatile unsigned cached_lines = 0;
94 size_t page_size(void) {
95 static thread_local size_t pgsz = 0;
98 if (_likely_(pgsz > 0))
101 r = sysconf(_SC_PAGESIZE);
108 bool streq_ptr(const char *a, const char *b) {
110 /* Like streq(), but tries to make sense of NULL pointers */
121 char* endswith(const char *s, const char *postfix) {
128 pl = strlen(postfix);
131 return (char*) s + sl;
136 if (memcmp(s + sl - pl, postfix, pl) != 0)
139 return (char*) s + sl - pl;
142 bool first_word(const char *s, const char *word) {
157 if (memcmp(s, word, wl) != 0)
161 strchr(WHITESPACE, s[wl]);
164 int close_nointr(int fd) {
170 /* Just ignore EINTR; a retry loop is the wrong
171 * thing to do on Linux.
173 * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
174 * https://bugzilla.gnome.org/show_bug.cgi?id=682819
175 * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
176 * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
178 if (_unlikely_(r < 0 && errno == EINTR))
186 void close_nointr_nofail(int fd) {
189 /* like close_nointr() but cannot fail, and guarantees errno
192 assert_se(close_nointr(fd) == 0);
195 void close_many(const int fds[], unsigned n_fd) {
198 assert(fds || n_fd <= 0);
200 for (i = 0; i < n_fd; i++)
201 close_nointr_nofail(fds[i]);
204 int unlink_noerrno(const char *path) {
215 int parse_boolean(const char *v) {
218 if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || strcaseeq(v, "on"))
220 else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || strcaseeq(v, "off"))
226 int parse_pid(const char *s, pid_t* ret_pid) {
227 unsigned long ul = 0;
234 r = safe_atolu(s, &ul);
240 if ((unsigned long) pid != ul)
250 int parse_uid(const char *s, uid_t* ret_uid) {
251 unsigned long ul = 0;
258 r = safe_atolu(s, &ul);
264 if ((unsigned long) uid != ul)
271 int safe_atou(const char *s, unsigned *ret_u) {
279 l = strtoul(s, &x, 0);
281 if (!x || x == s || *x || errno)
282 return errno > 0 ? -errno : -EINVAL;
284 if ((unsigned long) (unsigned) l != l)
287 *ret_u = (unsigned) l;
291 int safe_atoi(const char *s, int *ret_i) {
299 l = strtol(s, &x, 0);
301 if (!x || x == s || *x || errno)
302 return errno > 0 ? -errno : -EINVAL;
304 if ((long) (int) l != l)
311 int safe_atollu(const char *s, long long unsigned *ret_llu) {
313 unsigned long long l;
319 l = strtoull(s, &x, 0);
321 if (!x || x == s || *x || errno)
322 return errno ? -errno : -EINVAL;
328 int safe_atolli(const char *s, long long int *ret_lli) {
336 l = strtoll(s, &x, 0);
338 if (!x || x == s || *x || errno)
339 return errno ? -errno : -EINVAL;
345 int safe_atod(const char *s, double *ret_d) {
352 RUN_WITH_LOCALE(LC_NUMERIC_MASK, "C") {
357 if (!x || x == s || *x || errno)
358 return errno ? -errno : -EINVAL;
364 static size_t strcspn_escaped(const char *s, const char *reject) {
365 bool escaped = false;
368 for (n=0; s[n]; n++) {
371 else if (s[n] == '\\')
373 else if (strchr(reject, s[n]))
379 /* Split a string into words. */
380 char *split(const char *c, size_t *l, const char *separator, bool quoted, char **state) {
383 current = *state ? *state : (char*) c;
385 if (!*current || *c == 0)
388 current += strspn(current, separator);
392 if (quoted && strchr("\'\"", *current)) {
393 char quotechar = *(current++);
394 *l = strcspn_escaped(current, (char[]){quotechar, '\0'});
395 *state = current+*l+1;
397 *l = strcspn_escaped(current, separator);
400 *l = strcspn(current, separator);
404 return (char*) current;
407 int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
409 _cleanup_free_ char *line = NULL;
421 p = procfs_file_alloca(pid, "stat");
422 r = read_one_line_file(p, &line);
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 */
430 p = strrchr(line, ')');
442 if ((long unsigned) (pid_t) ppid != ppid)
445 *_ppid = (pid_t) ppid;
450 int get_starttime_of_pid(pid_t pid, unsigned long long *st) {
452 _cleanup_free_ char *line = NULL;
458 p = procfs_file_alloca(pid, "stat");
459 r = read_one_line_file(p, &line);
463 /* Let's skip the pid and comm fields. The latter is enclosed
464 * in () but does not escape any () in its value, so let's
465 * skip over it manually */
467 p = strrchr(line, ')');
489 "%*d " /* priority */
491 "%*d " /* num_threads */
492 "%*d " /* itrealvalue */
493 "%llu " /* starttime */,
500 int fchmod_umask(int fd, mode_t m) {
505 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
511 char *truncate_nl(char *s) {
514 s[strcspn(s, NEWLINE)] = 0;
518 int get_process_state(pid_t pid) {
522 _cleanup_free_ char *line = NULL;
526 p = procfs_file_alloca(pid, "stat");
527 r = read_one_line_file(p, &line);
531 p = strrchr(line, ')');
537 if (sscanf(p, " %c", &state) != 1)
540 return (unsigned char) state;
543 int get_process_comm(pid_t pid, char **name) {
550 p = procfs_file_alloca(pid, "comm");
552 r = read_one_line_file(p, name);
559 int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
560 _cleanup_fclose_ FILE *f = NULL;
568 p = procfs_file_alloca(pid, "cmdline");
574 if (max_length == 0) {
575 size_t len = 0, allocated = 0;
577 while ((c = getc(f)) != EOF) {
579 if (!GREEDY_REALLOC(r, allocated, len+2)) {
584 r[len++] = isprint(c) ? c : ' ';
594 r = new(char, max_length);
600 while ((c = getc(f)) != EOF) {
622 size_t n = MIN(left-1, 3U);
629 /* Kernel threads have no argv[] */
630 if (r == NULL || r[0] == 0) {
631 _cleanup_free_ char *t = NULL;
639 h = get_process_comm(pid, &t);
643 r = strjoin("[", t, "]", NULL);
652 int is_kernel_thread(pid_t pid) {
664 p = procfs_file_alloca(pid, "cmdline");
669 count = fread(&c, 1, 1, f);
673 /* Kernel threads have an empty cmdline */
676 return eof ? 1 : -errno;
681 int get_process_capeff(pid_t pid, char **capeff) {
687 p = procfs_file_alloca(pid, "status");
689 return get_status_field(p, "\nCapEff:", capeff);
692 int get_process_exe(pid_t pid, char **name) {
700 p = procfs_file_alloca(pid, "exe");
702 r = readlink_malloc(p, name);
704 return r == -ENOENT ? -ESRCH : r;
706 d = endswith(*name, " (deleted)");
713 static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
714 _cleanup_fclose_ FILE *f = NULL;
724 p = procfs_file_alloca(pid, "status");
729 FOREACH_LINE(line, f, return -errno) {
734 if (startswith(l, field)) {
736 l += strspn(l, WHITESPACE);
738 l[strcspn(l, WHITESPACE)] = 0;
740 return parse_uid(l, uid);
747 int get_process_uid(pid_t pid, uid_t *uid) {
748 return get_process_id(pid, "Uid:", uid);
751 int get_process_gid(pid_t pid, gid_t *gid) {
752 assert_cc(sizeof(uid_t) == sizeof(gid_t));
753 return get_process_id(pid, "Gid:", gid);
756 char *strnappend(const char *s, const char *suffix, size_t b) {
764 return strndup(suffix, b);
773 if (b > ((size_t) -1) - a)
776 r = new(char, a+b+1);
781 memcpy(r+a, suffix, b);
787 char *strappend(const char *s, const char *suffix) {
788 return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
791 int readlink_malloc(const char *p, char **ret) {
806 n = readlink(p, c, l-1);
813 if ((size_t) n < l-1) {
824 int readlink_and_make_absolute(const char *p, char **r) {
825 _cleanup_free_ char *target = NULL;
832 j = readlink_malloc(p, &target);
836 k = file_in_same_dir(p, target);
844 int readlink_and_canonicalize(const char *p, char **r) {
851 j = readlink_and_make_absolute(p, &t);
855 s = canonicalize_file_name(t);
862 path_kill_slashes(*r);
867 int reset_all_signal_handlers(void) {
870 for (sig = 1; sig < _NSIG; sig++) {
871 struct sigaction sa = {
872 .sa_handler = SIG_DFL,
873 .sa_flags = SA_RESTART,
876 if (sig == SIGKILL || sig == SIGSTOP)
879 /* On Linux the first two RT signals are reserved by
880 * glibc, and sigaction() will return EINVAL for them. */
881 if ((sigaction(sig, &sa, NULL) < 0))
889 char *strstrip(char *s) {
892 /* Drops trailing whitespace. Modifies the string in
893 * place. Returns pointer to first non-space character */
895 s += strspn(s, WHITESPACE);
897 for (e = strchr(s, 0); e > s; e --)
898 if (!strchr(WHITESPACE, e[-1]))
906 char *delete_chars(char *s, const char *bad) {
909 /* Drops all whitespace, regardless where in the string */
911 for (f = s, t = s; *f; f++) {
923 bool in_charset(const char *s, const char* charset) {
930 if (!strchr(charset, *i))
936 char *file_in_same_dir(const char *path, const char *filename) {
943 /* This removes the last component of path and appends
944 * filename, unless the latter is absolute anyway or the
947 if (path_is_absolute(filename))
948 return strdup(filename);
950 if (!(e = strrchr(path, '/')))
951 return strdup(filename);
953 k = strlen(filename);
954 if (!(r = new(char, e-path+1+k+1)))
957 memcpy(r, path, e-path+1);
958 memcpy(r+(e-path)+1, filename, k+1);
963 int rmdir_parents(const char *path, const char *stop) {
972 /* Skip trailing slashes */
973 while (l > 0 && path[l-1] == '/')
979 /* Skip last component */
980 while (l > 0 && path[l-1] != '/')
983 /* Skip trailing slashes */
984 while (l > 0 && path[l-1] == '/')
990 if (!(t = strndup(path, l)))
993 if (path_startswith(stop, t)) {
1002 if (errno != ENOENT)
1009 char hexchar(int x) {
1010 static const char table[16] = "0123456789abcdef";
1012 return table[x & 15];
1015 int unhexchar(char c) {
1017 if (c >= '0' && c <= '9')
1020 if (c >= 'a' && c <= 'f')
1021 return c - 'a' + 10;
1023 if (c >= 'A' && c <= 'F')
1024 return c - 'A' + 10;
1029 char *hexmem(const void *p, size_t l) {
1033 z = r = malloc(l * 2 + 1);
1037 for (x = p; x < (const uint8_t*) p + l; x++) {
1038 *(z++) = hexchar(*x >> 4);
1039 *(z++) = hexchar(*x & 15);
1046 void *unhexmem(const char *p, size_t l) {
1052 z = r = malloc((l + 1) / 2 + 1);
1056 for (x = p; x < p + l; x += 2) {
1059 a = unhexchar(x[0]);
1061 b = unhexchar(x[1]);
1065 *(z++) = (uint8_t) a << 4 | (uint8_t) b;
1072 char octchar(int x) {
1073 return '0' + (x & 7);
1076 int unoctchar(char c) {
1078 if (c >= '0' && c <= '7')
1084 char decchar(int x) {
1085 return '0' + (x % 10);
1088 int undecchar(char c) {
1090 if (c >= '0' && c <= '9')
1096 char *cescape(const char *s) {
1102 /* Does C style string escaping. */
1104 r = new(char, strlen(s)*4 + 1);
1108 for (f = s, t = r; *f; f++)
1154 /* For special chars we prefer octal over
1155 * hexadecimal encoding, simply because glib's
1156 * g_strescape() does the same */
1157 if ((*f < ' ') || (*f >= 127)) {
1159 *(t++) = octchar((unsigned char) *f >> 6);
1160 *(t++) = octchar((unsigned char) *f >> 3);
1161 *(t++) = octchar((unsigned char) *f);
1172 char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix) {
1179 /* Undoes C style string escaping, and optionally prefixes it. */
1181 pl = prefix ? strlen(prefix) : 0;
1183 r = new(char, pl+length+1);
1188 memcpy(r, prefix, pl);
1190 for (f = s, t = r + pl; f < s + length; f++) {
1233 /* This is an extension of the XDG syntax files */
1238 /* hexadecimal encoding */
1241 a = unhexchar(f[1]);
1242 b = unhexchar(f[2]);
1244 if (a < 0 || b < 0) {
1245 /* Invalid escape code, let's take it literal then */
1249 *(t++) = (char) ((a << 4) | b);
1264 /* octal encoding */
1267 a = unoctchar(f[0]);
1268 b = unoctchar(f[1]);
1269 c = unoctchar(f[2]);
1271 if (a < 0 || b < 0 || c < 0) {
1272 /* Invalid escape code, let's take it literal then */
1276 *(t++) = (char) ((a << 6) | (b << 3) | c);
1284 /* premature end of string.*/
1289 /* Invalid escape code, let's take it literal then */
1301 char *cunescape_length(const char *s, size_t length) {
1302 return cunescape_length_with_prefix(s, length, NULL);
1305 char *cunescape(const char *s) {
1308 return cunescape_length(s, strlen(s));
1311 char *xescape(const char *s, const char *bad) {
1315 /* Escapes all chars in bad, in addition to \ and all special
1316 * chars, in \xFF style escaping. May be reversed with
1319 r = new(char, strlen(s) * 4 + 1);
1323 for (f = s, t = r; *f; f++) {
1325 if ((*f < ' ') || (*f >= 127) ||
1326 (*f == '\\') || strchr(bad, *f)) {
1329 *(t++) = hexchar(*f >> 4);
1330 *(t++) = hexchar(*f);
1340 char *ascii_strlower(char *t) {
1345 for (p = t; *p; p++)
1346 if (*p >= 'A' && *p <= 'Z')
1347 *p = *p - 'A' + 'a';
1352 _pure_ static bool ignore_file_allow_backup(const char *filename) {
1356 filename[0] == '.' ||
1357 streq(filename, "lost+found") ||
1358 streq(filename, "aquota.user") ||
1359 streq(filename, "aquota.group") ||
1360 endswith(filename, ".rpmnew") ||
1361 endswith(filename, ".rpmsave") ||
1362 endswith(filename, ".rpmorig") ||
1363 endswith(filename, ".dpkg-old") ||
1364 endswith(filename, ".dpkg-new") ||
1365 endswith(filename, ".swp");
1368 bool ignore_file(const char *filename) {
1371 if (endswith(filename, "~"))
1374 return ignore_file_allow_backup(filename);
1377 int fd_nonblock(int fd, bool nonblock) {
1382 if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
1386 flags |= O_NONBLOCK;
1388 flags &= ~O_NONBLOCK;
1390 if (fcntl(fd, F_SETFL, flags) < 0)
1396 int fd_cloexec(int fd, bool cloexec) {
1401 if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
1405 flags |= FD_CLOEXEC;
1407 flags &= ~FD_CLOEXEC;
1409 if (fcntl(fd, F_SETFD, flags) < 0)
1415 _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
1418 assert(n_fdset == 0 || fdset);
1420 for (i = 0; i < n_fdset; i++)
1427 int close_all_fds(const int except[], unsigned n_except) {
1432 assert(n_except == 0 || except);
1434 d = opendir("/proc/self/fd");
1439 /* When /proc isn't available (for example in chroots)
1440 * the fallback is brute forcing through the fd
1443 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
1444 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
1446 if (fd_in_set(fd, except, n_except))
1449 if (close_nointr(fd) < 0)
1450 if (errno != EBADF && r == 0)
1457 while ((de = readdir(d))) {
1460 if (ignore_file(de->d_name))
1463 if (safe_atoi(de->d_name, &fd) < 0)
1464 /* Let's better ignore this, just in case */
1473 if (fd_in_set(fd, except, n_except))
1476 if (close_nointr(fd) < 0) {
1477 /* Valgrind has its own FD and doesn't want to have it closed */
1478 if (errno != EBADF && r == 0)
1487 bool chars_intersect(const char *a, const char *b) {
1490 /* Returns true if any of the chars in a are in b. */
1491 for (p = a; *p; p++)
1498 bool fstype_is_network(const char *fstype) {
1499 static const char table[] =
1509 return nulstr_contains(table, fstype);
1513 _cleanup_close_ int fd;
1515 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
1521 TIOCL_GETKMSGREDIRECT,
1525 if (ioctl(fd, TIOCLINUX, tiocl) < 0)
1528 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
1531 if (ioctl(fd, VT_ACTIVATE, vt) < 0)
1537 int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
1538 struct termios old_termios, new_termios;
1540 char line[LINE_MAX];
1545 if (tcgetattr(fileno(f), &old_termios) >= 0) {
1546 new_termios = old_termios;
1548 new_termios.c_lflag &= ~ICANON;
1549 new_termios.c_cc[VMIN] = 1;
1550 new_termios.c_cc[VTIME] = 0;
1552 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
1555 if (t != (usec_t) -1) {
1556 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
1557 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
1562 k = fread(&c, 1, 1, f);
1564 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
1570 *need_nl = c != '\n';
1577 if (t != (usec_t) -1)
1578 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
1581 if (!fgets(line, sizeof(line), f))
1586 if (strlen(line) != 1)
1596 int ask(char *ret, const char *replies, const char *text, ...) {
1606 bool need_nl = true;
1609 fputs(ANSI_HIGHLIGHT_ON, stdout);
1616 fputs(ANSI_HIGHLIGHT_OFF, stdout);
1620 r = read_one_char(stdin, &c, (usec_t) -1, &need_nl);
1623 if (r == -EBADMSG) {
1624 puts("Bad input, please try again.");
1635 if (strchr(replies, c)) {
1640 puts("Read unexpected character, please try again.");
1644 int reset_terminal_fd(int fd, bool switch_to_text) {
1645 struct termios termios;
1648 /* Set terminal to some sane defaults */
1652 /* We leave locked terminal attributes untouched, so that
1653 * Plymouth may set whatever it wants to set, and we don't
1654 * interfere with that. */
1656 /* Disable exclusive mode, just in case */
1657 ioctl(fd, TIOCNXCL);
1659 /* Switch to text mode */
1661 ioctl(fd, KDSETMODE, KD_TEXT);
1663 /* Enable console unicode mode */
1664 ioctl(fd, KDSKBMODE, K_UNICODE);
1666 if (tcgetattr(fd, &termios) < 0) {
1671 /* We only reset the stuff that matters to the software. How
1672 * hardware is set up we don't touch assuming that somebody
1673 * else will do that for us */
1675 termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
1676 termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
1677 termios.c_oflag |= ONLCR;
1678 termios.c_cflag |= CREAD;
1679 termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
1681 termios.c_cc[VINTR] = 03; /* ^C */
1682 termios.c_cc[VQUIT] = 034; /* ^\ */
1683 termios.c_cc[VERASE] = 0177;
1684 termios.c_cc[VKILL] = 025; /* ^X */
1685 termios.c_cc[VEOF] = 04; /* ^D */
1686 termios.c_cc[VSTART] = 021; /* ^Q */
1687 termios.c_cc[VSTOP] = 023; /* ^S */
1688 termios.c_cc[VSUSP] = 032; /* ^Z */
1689 termios.c_cc[VLNEXT] = 026; /* ^V */
1690 termios.c_cc[VWERASE] = 027; /* ^W */
1691 termios.c_cc[VREPRINT] = 022; /* ^R */
1692 termios.c_cc[VEOL] = 0;
1693 termios.c_cc[VEOL2] = 0;
1695 termios.c_cc[VTIME] = 0;
1696 termios.c_cc[VMIN] = 1;
1698 if (tcsetattr(fd, TCSANOW, &termios) < 0)
1702 /* Just in case, flush all crap out */
1703 tcflush(fd, TCIOFLUSH);
1708 int reset_terminal(const char *name) {
1711 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
1715 r = reset_terminal_fd(fd, true);
1716 close_nointr_nofail(fd);
1721 int open_terminal(const char *name, int mode) {
1726 * If a TTY is in the process of being closed opening it might
1727 * cause EIO. This is horribly awful, but unlikely to be
1728 * changed in the kernel. Hence we work around this problem by
1729 * retrying a couple of times.
1731 * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
1734 assert(!(mode & O_CREAT));
1737 fd = open(name, mode, 0);
1744 /* Max 1s in total */
1748 usleep(50 * USEC_PER_MSEC);
1757 close_nointr_nofail(fd);
1762 close_nointr_nofail(fd);
1769 int flush_fd(int fd) {
1770 struct pollfd pollfd = {
1780 r = poll(&pollfd, 1, 0);
1790 l = read(fd, buf, sizeof(buf));
1796 if (errno == EAGAIN)
1805 int acquire_terminal(
1809 bool ignore_tiocstty_eperm,
1812 int fd = -1, notify = -1, r = 0, wd = -1;
1817 /* We use inotify to be notified when the tty is closed. We
1818 * create the watch before checking if we can actually acquire
1819 * it, so that we don't lose any event.
1821 * Note: strictly speaking this actually watches for the
1822 * device being closed, it does *not* really watch whether a
1823 * tty loses its controlling process. However, unless some
1824 * rogue process uses TIOCNOTTY on /dev/tty *after* closing
1825 * its tty otherwise this will not become a problem. As long
1826 * as the administrator makes sure not configure any service
1827 * on the same tty as an untrusted user this should not be a
1828 * problem. (Which he probably should not do anyway.) */
1830 if (timeout != (usec_t) -1)
1831 ts = now(CLOCK_MONOTONIC);
1833 if (!fail && !force) {
1834 notify = inotify_init1(IN_CLOEXEC | (timeout != (usec_t) -1 ? IN_NONBLOCK : 0));
1840 wd = inotify_add_watch(notify, name, IN_CLOSE);
1848 struct sigaction sa_old, sa_new = {
1849 .sa_handler = SIG_IGN,
1850 .sa_flags = SA_RESTART,
1854 r = flush_fd(notify);
1859 /* We pass here O_NOCTTY only so that we can check the return
1860 * value TIOCSCTTY and have a reliable way to figure out if we
1861 * successfully became the controlling process of the tty */
1862 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
1866 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
1867 * if we already own the tty. */
1868 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
1870 /* First, try to get the tty */
1871 if (ioctl(fd, TIOCSCTTY, force) < 0)
1874 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
1876 /* Sometimes it makes sense to ignore TIOCSCTTY
1877 * returning EPERM, i.e. when very likely we already
1878 * are have this controlling terminal. */
1879 if (r < 0 && r == -EPERM && ignore_tiocstty_eperm)
1882 if (r < 0 && (force || fail || r != -EPERM)) {
1891 assert(notify >= 0);
1894 uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
1896 struct inotify_event *e;
1898 if (timeout != (usec_t) -1) {
1901 n = now(CLOCK_MONOTONIC);
1902 if (ts + timeout < n) {
1907 r = fd_wait_for_event(fd, POLLIN, ts + timeout - n);
1917 l = read(notify, inotify_buffer, sizeof(inotify_buffer));
1920 if (errno == EINTR || errno == EAGAIN)
1927 e = (struct inotify_event*) inotify_buffer;
1932 if (e->wd != wd || !(e->mask & IN_CLOSE)) {
1937 step = sizeof(struct inotify_event) + e->len;
1938 assert(step <= (size_t) l);
1940 e = (struct inotify_event*) ((uint8_t*) e + step);
1947 /* We close the tty fd here since if the old session
1948 * ended our handle will be dead. It's important that
1949 * we do this after sleeping, so that we don't enter
1950 * an endless loop. */
1951 close_nointr_nofail(fd);
1955 close_nointr_nofail(notify);
1957 r = reset_terminal_fd(fd, true);
1959 log_warning("Failed to reset terminal: %s", strerror(-r));
1965 close_nointr_nofail(fd);
1968 close_nointr_nofail(notify);
1973 int release_terminal(void) {
1975 struct sigaction sa_old, sa_new = {
1976 .sa_handler = SIG_IGN,
1977 .sa_flags = SA_RESTART,
1979 _cleanup_close_ int fd;
1981 fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC);
1985 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
1986 * by our own TIOCNOTTY */
1987 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
1989 if (ioctl(fd, TIOCNOTTY) < 0)
1992 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
1997 int sigaction_many(const struct sigaction *sa, ...) {
2002 while ((sig = va_arg(ap, int)) > 0)
2003 if (sigaction(sig, sa, NULL) < 0)
2010 int ignore_signals(int sig, ...) {
2011 struct sigaction sa = {
2012 .sa_handler = SIG_IGN,
2013 .sa_flags = SA_RESTART,
2019 if (sigaction(sig, &sa, NULL) < 0)
2023 while ((sig = va_arg(ap, int)) > 0)
2024 if (sigaction(sig, &sa, NULL) < 0)
2031 int default_signals(int sig, ...) {
2032 struct sigaction sa = {
2033 .sa_handler = SIG_DFL,
2034 .sa_flags = SA_RESTART,
2039 if (sigaction(sig, &sa, NULL) < 0)
2043 while ((sig = va_arg(ap, int)) > 0)
2044 if (sigaction(sig, &sa, NULL) < 0)
2051 int close_pipe(int p[]) {
2057 a = close_nointr(p[0]);
2062 b = close_nointr(p[1]);
2066 return a < 0 ? a : b;
2069 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2076 while (nbytes > 0) {
2079 k = read(fd, p, nbytes);
2080 if (k < 0 && errno == EINTR)
2083 if (k < 0 && errno == EAGAIN && do_poll) {
2085 /* We knowingly ignore any return value here,
2086 * and expect that any error/EOF is reported
2089 fd_wait_for_event(fd, POLLIN, (usec_t) -1);
2094 return n > 0 ? n : (k < 0 ? -errno : 0);
2104 ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2105 const uint8_t *p = buf;
2111 while (nbytes > 0) {
2114 k = write(fd, p, nbytes);
2115 if (k < 0 && errno == EINTR)
2118 if (k < 0 && errno == EAGAIN && do_poll) {
2120 /* We knowingly ignore any return value here,
2121 * and expect that any error/EOF is reported
2124 fd_wait_for_event(fd, POLLOUT, (usec_t) -1);
2129 return n > 0 ? n : (k < 0 ? -errno : 0);
2139 int parse_size(const char *t, off_t base, off_t *size) {
2141 /* Soo, sometimes we want to parse IEC binary suffxies, and
2142 * sometimes SI decimal suffixes. This function can parse
2143 * both. Which one is the right way depends on the
2144 * context. Wikipedia suggests that SI is customary for
2145 * hardrware metrics and network speeds, while IEC is
2146 * customary for most data sizes used by software and volatile
2147 * (RAM) memory. Hence be careful which one you pick!
2149 * In either case we use just K, M, G as suffix, and not Ki,
2150 * Mi, Gi or so (as IEC would suggest). That's because that's
2151 * frickin' ugly. But this means you really need to make sure
2152 * to document which base you are parsing when you use this
2157 unsigned long long factor;
2160 static const struct table iec[] = {
2161 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2162 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2163 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2164 { "G", 1024ULL*1024ULL*1024ULL },
2165 { "M", 1024ULL*1024ULL },
2171 static const struct table si[] = {
2172 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2173 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2174 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
2175 { "G", 1000ULL*1000ULL*1000ULL },
2176 { "M", 1000ULL*1000ULL },
2182 const struct table *table;
2184 unsigned long long r = 0;
2185 unsigned n_entries, start_pos = 0;
2188 assert(base == 1000 || base == 1024);
2193 n_entries = ELEMENTSOF(si);
2196 n_entries = ELEMENTSOF(iec);
2202 unsigned long long l2;
2208 l = strtoll(p, &e, 10);
2221 if (*e >= '0' && *e <= '9') {
2224 /* strotoull itself would accept space/+/- */
2225 l2 = strtoull(e, &e2, 10);
2227 if (errno == ERANGE)
2230 /* Ignore failure. E.g. 10.M is valid */
2237 e += strspn(e, WHITESPACE);
2239 for (i = start_pos; i < n_entries; i++)
2240 if (startswith(e, table[i].suffix)) {
2241 unsigned long long tmp;
2242 if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor)
2244 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
2245 if (tmp > ULLONG_MAX - r)
2249 if ((unsigned long long) (off_t) r != r)
2252 p = e + strlen(table[i].suffix);
2268 int make_stdio(int fd) {
2273 r = dup3(fd, STDIN_FILENO, 0);
2274 s = dup3(fd, STDOUT_FILENO, 0);
2275 t = dup3(fd, STDERR_FILENO, 0);
2278 close_nointr_nofail(fd);
2280 if (r < 0 || s < 0 || t < 0)
2283 /* We rely here that the new fd has O_CLOEXEC not set */
2288 int make_null_stdio(void) {
2291 null_fd = open("/dev/null", O_RDWR|O_NOCTTY);
2295 return make_stdio(null_fd);
2298 bool is_device_path(const char *path) {
2300 /* Returns true on paths that refer to a device, either in
2301 * sysfs or in /dev */
2304 path_startswith(path, "/dev/") ||
2305 path_startswith(path, "/sys/");
2308 int dir_is_empty(const char *path) {
2309 _cleanup_closedir_ DIR *d;
2320 if (!de && errno != 0)
2326 if (!ignore_file(de->d_name))
2331 char* dirname_malloc(const char *path) {
2332 char *d, *dir, *dir2;
2349 int dev_urandom(void *p, size_t n) {
2350 _cleanup_close_ int fd;
2353 fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
2355 return errno == ENOENT ? -ENOSYS : -errno;
2357 k = loop_read(fd, p, n, true);
2360 if ((size_t) k != n)
2366 void random_bytes(void *p, size_t n) {
2367 static bool srand_called = false;
2371 r = dev_urandom(p, n);
2375 /* If some idiot made /dev/urandom unavailable to us, he'll
2376 * get a PRNG instead. */
2378 if (!srand_called) {
2381 #ifdef HAVE_SYS_AUXV_H
2382 /* The kernel provides us with a bit of entropy in
2383 * auxv, so let's try to make use of that to seed the
2384 * pseudo-random generator. It's better than
2389 auxv = (void*) getauxval(AT_RANDOM);
2391 x ^= *(unsigned*) auxv;
2394 x ^= (unsigned) now(CLOCK_REALTIME);
2395 x ^= (unsigned) gettid();
2398 srand_called = true;
2401 for (q = p; q < (uint8_t*) p + n; q ++)
2405 void rename_process(const char name[8]) {
2408 /* This is a like a poor man's setproctitle(). It changes the
2409 * comm field, argv[0], and also the glibc's internally used
2410 * name of the process. For the first one a limit of 16 chars
2411 * applies, to the second one usually one of 10 (i.e. length
2412 * of "/sbin/init"), to the third one one of 7 (i.e. length of
2413 * "systemd"). If you pass a longer string it will be
2416 prctl(PR_SET_NAME, name);
2418 if (program_invocation_name)
2419 strncpy(program_invocation_name, name, strlen(program_invocation_name));
2421 if (saved_argc > 0) {
2425 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
2427 for (i = 1; i < saved_argc; i++) {
2431 memzero(saved_argv[i], strlen(saved_argv[i]));
2436 void sigset_add_many(sigset_t *ss, ...) {
2443 while ((sig = va_arg(ap, int)) > 0)
2444 assert_se(sigaddset(ss, sig) == 0);
2448 char* gethostname_malloc(void) {
2451 assert_se(uname(&u) >= 0);
2453 if (!isempty(u.nodename) && !streq(u.nodename, "(none)"))
2454 return strdup(u.nodename);
2456 return strdup(u.sysname);
2459 bool hostname_is_set(void) {
2462 assert_se(uname(&u) >= 0);
2464 return !isempty(u.nodename) && !streq(u.nodename, "(none)");
2467 static char *lookup_uid(uid_t uid) {
2470 _cleanup_free_ char *buf = NULL;
2471 struct passwd pwbuf, *pw = NULL;
2473 /* Shortcut things to avoid NSS lookups */
2475 return strdup("root");
2477 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
2481 buf = malloc(bufsize);
2485 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
2486 return strdup(pw->pw_name);
2488 if (asprintf(&name, "%lu", (unsigned long) uid) < 0)
2494 char* getlogname_malloc(void) {
2498 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
2503 return lookup_uid(uid);
2506 char *getusername_malloc(void) {
2513 return lookup_uid(getuid());
2516 int getttyname_malloc(int fd, char **r) {
2517 char path[PATH_MAX], *c;
2522 k = ttyname_r(fd, path, sizeof(path));
2528 c = strdup(startswith(path, "/dev/") ? path + 5 : path);
2536 int getttyname_harder(int fd, char **r) {
2540 k = getttyname_malloc(fd, &s);
2544 if (streq(s, "tty")) {
2546 return get_ctty(0, NULL, r);
2553 int get_ctty_devnr(pid_t pid, dev_t *d) {
2555 _cleanup_free_ char *line = NULL;
2557 unsigned long ttynr;
2561 p = procfs_file_alloca(pid, "stat");
2562 r = read_one_line_file(p, &line);
2566 p = strrchr(line, ')');
2576 "%*d " /* session */
2581 if (major(ttynr) == 0 && minor(ttynr) == 0)
2590 int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
2591 char fn[sizeof("/dev/char/")-1 + 2*DECIMAL_STR_MAX(unsigned) + 1 + 1], *b = NULL;
2592 _cleanup_free_ char *s = NULL;
2599 k = get_ctty_devnr(pid, &devnr);
2603 snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
2605 k = readlink_malloc(fn, &s);
2611 /* This is an ugly hack */
2612 if (major(devnr) == 136) {
2613 asprintf(&b, "pts/%lu", (unsigned long) minor(devnr));
2617 /* Probably something like the ptys which have no
2618 * symlink in /dev/char. Let's return something
2619 * vaguely useful. */
2625 if (startswith(s, "/dev/"))
2627 else if (startswith(s, "../"))
2645 int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
2651 /* This returns the first error we run into, but nevertheless
2652 * tries to go on. This closes the passed fd. */
2656 close_nointr_nofail(fd);
2658 return errno == ENOENT ? 0 : -errno;
2663 bool is_dir, keep_around;
2669 if (!de && errno != 0) {
2678 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
2681 if (de->d_type == DT_UNKNOWN ||
2683 (de->d_type == DT_DIR && root_dev)) {
2684 if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
2685 if (ret == 0 && errno != ENOENT)
2690 is_dir = S_ISDIR(st.st_mode);
2693 (st.st_uid == 0 || st.st_uid == getuid()) &&
2694 (st.st_mode & S_ISVTX);
2696 is_dir = de->d_type == DT_DIR;
2697 keep_around = false;
2703 /* if root_dev is set, remove subdirectories only, if device is same as dir */
2704 if (root_dev && st.st_dev != root_dev->st_dev)
2707 subdir_fd = openat(fd, de->d_name,
2708 O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
2709 if (subdir_fd < 0) {
2710 if (ret == 0 && errno != ENOENT)
2715 r = rm_rf_children_dangerous(subdir_fd, only_dirs, honour_sticky, root_dev);
2716 if (r < 0 && ret == 0)
2720 if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
2721 if (ret == 0 && errno != ENOENT)
2725 } else if (!only_dirs && !keep_around) {
2727 if (unlinkat(fd, de->d_name, 0) < 0) {
2728 if (ret == 0 && errno != ENOENT)
2739 _pure_ static int is_temporary_fs(struct statfs *s) {
2742 return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) ||
2743 F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC);
2746 int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
2751 if (fstatfs(fd, &s) < 0) {
2752 close_nointr_nofail(fd);
2756 /* We refuse to clean disk file systems with this call. This
2757 * is extra paranoia just to be sure we never ever remove
2759 if (!is_temporary_fs(&s)) {
2760 log_error("Attempted to remove disk file system, and we can't allow that.");
2761 close_nointr_nofail(fd);
2765 return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev);
2768 static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
2774 /* We refuse to clean the root file system with this
2775 * call. This is extra paranoia to never cause a really
2776 * seriously broken system. */
2777 if (path_equal(path, "/")) {
2778 log_error("Attempted to remove entire root file system, and we can't allow that.");
2782 fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
2785 if (errno != ENOTDIR)
2789 if (statfs(path, &s) < 0)
2792 if (!is_temporary_fs(&s)) {
2793 log_error("Attempted to remove disk file system, and we can't allow that.");
2798 if (delete_root && !only_dirs)
2799 if (unlink(path) < 0 && errno != ENOENT)
2806 if (fstatfs(fd, &s) < 0) {
2807 close_nointr_nofail(fd);
2811 if (!is_temporary_fs(&s)) {
2812 log_error("Attempted to remove disk file system, and we can't allow that.");
2813 close_nointr_nofail(fd);
2818 r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL);
2821 if (honour_sticky && file_is_priv_sticky(path) > 0)
2824 if (rmdir(path) < 0 && errno != ENOENT) {
2833 int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
2834 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false);
2837 int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
2838 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, true);
2841 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
2844 /* Under the assumption that we are running privileged we
2845 * first change the access mode and only then hand out
2846 * ownership to avoid a window where access is too open. */
2848 if (mode != (mode_t) -1)
2849 if (chmod(path, mode) < 0)
2852 if (uid != (uid_t) -1 || gid != (gid_t) -1)
2853 if (chown(path, uid, gid) < 0)
2859 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
2862 /* Under the assumption that we are running privileged we
2863 * first change the access mode and only then hand out
2864 * ownership to avoid a window where access is too open. */
2866 if (mode != (mode_t) -1)
2867 if (fchmod(fd, mode) < 0)
2870 if (uid != (uid_t) -1 || gid != (gid_t) -1)
2871 if (fchown(fd, uid, gid) < 0)
2877 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
2881 /* Allocates the cpuset in the right size */
2884 if (!(r = CPU_ALLOC(n)))
2887 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
2888 CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
2898 if (errno != EINVAL)
2905 int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) {
2906 static const char status_indent[] = " "; /* "[" STATUS "] " */
2907 _cleanup_free_ char *s = NULL;
2908 _cleanup_close_ int fd = -1;
2909 struct iovec iovec[6] = {};
2911 static bool prev_ephemeral;
2915 /* This is independent of logging, as status messages are
2916 * optional and go exclusively to the console. */
2918 if (vasprintf(&s, format, ap) < 0)
2921 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
2934 sl = status ? sizeof(status_indent)-1 : 0;
2940 e = ellipsize(s, emax, 75);
2948 IOVEC_SET_STRING(iovec[n++], "\r" ANSI_ERASE_TO_END_OF_LINE);
2949 prev_ephemeral = ephemeral;
2952 if (!isempty(status)) {
2953 IOVEC_SET_STRING(iovec[n++], "[");
2954 IOVEC_SET_STRING(iovec[n++], status);
2955 IOVEC_SET_STRING(iovec[n++], "] ");
2957 IOVEC_SET_STRING(iovec[n++], status_indent);
2960 IOVEC_SET_STRING(iovec[n++], s);
2962 IOVEC_SET_STRING(iovec[n++], "\n");
2964 if (writev(fd, iovec, n) < 0)
2970 int status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...) {
2976 va_start(ap, format);
2977 r = status_vprintf(status, ellipse, ephemeral, format, ap);
2983 char *replace_env(const char *format, char **env) {
2990 const char *e, *word = format;
2995 for (e = format; *e; e ++) {
3006 if (!(k = strnappend(r, word, e-word-1)))
3015 } else if (*e == '$') {
3016 if (!(k = strnappend(r, word, e-word)))
3032 t = strempty(strv_env_get_n(env, word+2, e-word-2));
3034 k = strappend(r, t);
3048 if (!(k = strnappend(r, word, e-word)))
3059 char **replace_env_argv(char **argv, char **env) {
3061 unsigned k = 0, l = 0;
3063 l = strv_length(argv);
3065 if (!(r = new(char*, l+1)))
3068 STRV_FOREACH(i, argv) {
3070 /* If $FOO appears as single word, replace it by the split up variable */
3071 if ((*i)[0] == '$' && (*i)[1] != '{') {
3076 e = strv_env_get(env, *i+1);
3079 if (!(m = strv_split_quoted(e))) {
3090 if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
3099 memcpy(r + k, m, q * sizeof(char*));
3107 /* If ${FOO} appears as part of a word, replace it by the variable as-is */
3108 if (!(r[k++] = replace_env(*i, env))) {
3118 int fd_columns(int fd) {
3119 struct winsize ws = {};
3121 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3130 unsigned columns(void) {
3134 if (_likely_(cached_columns > 0))
3135 return cached_columns;
3138 e = getenv("COLUMNS");
3143 c = fd_columns(STDOUT_FILENO);
3152 int fd_lines(int fd) {
3153 struct winsize ws = {};
3155 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3164 unsigned lines(void) {
3168 if (_likely_(cached_lines > 0))
3169 return cached_lines;
3172 e = getenv("LINES");
3177 l = fd_lines(STDOUT_FILENO);
3183 return cached_lines;
3186 /* intended to be used as a SIGWINCH sighandler */
3187 void columns_lines_cache_reset(int signum) {
3193 static int cached_on_tty = -1;
3195 if (_unlikely_(cached_on_tty < 0))
3196 cached_on_tty = isatty(STDOUT_FILENO) > 0;
3198 return cached_on_tty;
3201 int files_same(const char *filea, const char *fileb) {
3204 if (stat(filea, &a) < 0)
3207 if (stat(fileb, &b) < 0)
3210 return a.st_dev == b.st_dev &&
3211 a.st_ino == b.st_ino;
3214 int running_in_chroot(void) {
3217 ret = files_same("/proc/1/root", "/");
3224 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
3229 assert(percent <= 100);
3230 assert(new_length >= 3);
3232 if (old_length <= 3 || old_length <= new_length)
3233 return strndup(s, old_length);
3235 r = new0(char, new_length+1);
3239 x = (new_length * percent) / 100;
3241 if (x > new_length - 3)
3249 s + old_length - (new_length - x - 3),
3250 new_length - x - 3);
3255 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
3259 unsigned k, len, len2;
3262 assert(percent <= 100);
3263 assert(new_length >= 3);
3265 /* if no multibyte characters use ascii_ellipsize_mem for speed */
3266 if (ascii_is_valid(s))
3267 return ascii_ellipsize_mem(s, old_length, new_length, percent);
3269 if (old_length <= 3 || old_length <= new_length)
3270 return strndup(s, old_length);
3272 x = (new_length * percent) / 100;
3274 if (x > new_length - 3)
3278 for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
3281 c = utf8_encoded_to_unichar(i);
3284 k += unichar_iswide(c) ? 2 : 1;
3287 if (k > x) /* last character was wide and went over quota */
3290 for (j = s + old_length; k < new_length && j > i; ) {
3293 j = utf8_prev_char(j);
3294 c = utf8_encoded_to_unichar(j);
3297 k += unichar_iswide(c) ? 2 : 1;
3301 /* we don't actually need to ellipsize */
3303 return memdup(s, old_length + 1);
3305 /* make space for ellipsis */
3306 j = utf8_next_char(j);
3309 len2 = s + old_length - j;
3310 e = new(char, len + 3 + len2 + 1);
3315 printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
3316 old_length, new_length, x, len, len2, k);
3320 e[len] = 0xe2; /* tri-dot ellipsis: … */
3324 memcpy(e + len + 3, j, len2 + 1);
3329 char *ellipsize(const char *s, size_t length, unsigned percent) {
3330 return ellipsize_mem(s, strlen(s), length, percent);
3333 int touch(const char *path) {
3338 /* This just opens the file for writing, ensuring it
3339 * exists. It doesn't call utimensat() the way /usr/bin/touch
3342 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644);
3346 close_nointr_nofail(fd);
3350 char *unquote(const char *s, const char* quotes) {
3354 /* This is rather stupid, simply removes the heading and
3355 * trailing quotes if there is one. Doesn't care about
3356 * escaping or anything. We should make this smarter one
3363 if (strchr(quotes, s[0]) && s[l-1] == s[0])
3364 return strndup(s+1, l-2);
3369 char *normalize_env_assignment(const char *s) {
3370 _cleanup_free_ char *name = NULL, *value = NULL, *p = NULL;
3373 eq = strchr(s, '=');
3385 memmove(r, t, strlen(t) + 1);
3389 name = strndup(s, eq - s);
3397 value = unquote(strstrip(p), QUOTES);
3401 if (asprintf(&r, "%s=%s", strstrip(name), value) < 0)
3407 int wait_for_terminate(pid_t pid, siginfo_t *status) {
3418 if (waitid(P_PID, pid, status, WEXITED) < 0) {
3430 int wait_for_terminate_and_warn(const char *name, pid_t pid) {
3437 r = wait_for_terminate(pid, &status);
3439 log_warning("Failed to wait for %s: %s", name, strerror(-r));
3443 if (status.si_code == CLD_EXITED) {
3444 if (status.si_status != 0) {
3445 log_warning("%s failed with error code %i.", name, status.si_status);
3446 return status.si_status;
3449 log_debug("%s succeeded.", name);
3452 } else if (status.si_code == CLD_KILLED ||
3453 status.si_code == CLD_DUMPED) {
3455 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
3459 log_warning("%s failed due to unknown reason.", name);
3463 noreturn void freeze(void) {
3465 /* Make sure nobody waits for us on a socket anymore */
3466 close_all_fds(NULL, 0);
3474 bool null_or_empty(struct stat *st) {
3477 if (S_ISREG(st->st_mode) && st->st_size <= 0)
3480 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
3486 int null_or_empty_path(const char *fn) {
3491 if (stat(fn, &st) < 0)
3494 return null_or_empty(&st);
3497 DIR *xopendirat(int fd, const char *name, int flags) {
3501 assert(!(flags & O_CREAT));
3503 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
3509 close_nointr_nofail(nfd);
3516 int signal_from_string_try_harder(const char *s) {
3520 signo = signal_from_string(s);
3522 if (startswith(s, "SIG"))
3523 return signal_from_string(s+3);
3528 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
3529 _cleanup_free_ char *t = NULL, *u = NULL;
3532 u = unquote(tagvalue, "\"\'");
3536 enc_len = strlen(u) * 4 + 1;
3537 t = new(char, enc_len);
3541 if (encode_devnode_name(u, t, enc_len) < 0)
3544 return strjoin("/dev/disk/by-", by, "/", t, NULL);
3547 char *fstab_node_to_udev_node(const char *p) {
3550 if (startswith(p, "LABEL="))
3551 return tag_to_udev_node(p+6, "label");
3553 if (startswith(p, "UUID="))
3554 return tag_to_udev_node(p+5, "uuid");
3556 if (startswith(p, "PARTUUID="))
3557 return tag_to_udev_node(p+9, "partuuid");
3559 if (startswith(p, "PARTLABEL="))
3560 return tag_to_udev_node(p+10, "partlabel");
3565 bool tty_is_vc(const char *tty) {
3568 if (startswith(tty, "/dev/"))
3571 return vtnr_from_tty(tty) >= 0;
3574 bool tty_is_console(const char *tty) {
3577 if (startswith(tty, "/dev/"))
3580 return streq(tty, "console");
3583 int vtnr_from_tty(const char *tty) {
3588 if (startswith(tty, "/dev/"))
3591 if (!startswith(tty, "tty") )
3594 if (tty[3] < '0' || tty[3] > '9')
3597 r = safe_atoi(tty+3, &i);
3601 if (i < 0 || i > 63)
3607 char *resolve_dev_console(char **active) {
3610 /* Resolve where /dev/console is pointing to, if /sys is actually ours
3611 * (i.e. not read-only-mounted which is a sign for container setups) */
3613 if (path_is_read_only_fs("/sys") > 0)
3616 if (read_one_line_file("/sys/class/tty/console/active", active) < 0)
3619 /* If multiple log outputs are configured the last one is what
3620 * /dev/console points to */
3621 tty = strrchr(*active, ' ');
3627 if (streq(tty, "tty0")) {
3630 /* Get the active VC (e.g. tty1) */
3631 if (read_one_line_file("/sys/class/tty/tty0/active", &tmp) >= 0) {
3633 tty = *active = tmp;
3640 bool tty_is_vc_resolve(const char *tty) {
3641 _cleanup_free_ char *active = NULL;
3645 if (startswith(tty, "/dev/"))
3648 if (streq(tty, "console")) {
3649 tty = resolve_dev_console(&active);
3654 return tty_is_vc(tty);
3657 const char *default_term_for_tty(const char *tty) {
3660 return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102";
3663 bool dirent_is_file(const struct dirent *de) {
3666 if (ignore_file(de->d_name))
3669 if (de->d_type != DT_REG &&
3670 de->d_type != DT_LNK &&
3671 de->d_type != DT_UNKNOWN)
3677 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
3680 if (de->d_type != DT_REG &&
3681 de->d_type != DT_LNK &&
3682 de->d_type != DT_UNKNOWN)
3685 if (ignore_file_allow_backup(de->d_name))
3688 return endswith(de->d_name, suffix);
3691 void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv[]) {
3697 /* Executes all binaries in a directory in parallel and waits
3698 * for them to finish. Optionally a timeout is applied. */
3700 executor_pid = fork();
3701 if (executor_pid < 0) {
3702 log_error("Failed to fork: %m");
3705 } else if (executor_pid == 0) {
3706 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
3707 _cleanup_closedir_ DIR *_d = NULL;
3711 /* We fork this all off from a child process so that
3712 * we can somewhat cleanly make use of SIGALRM to set
3715 reset_all_signal_handlers();
3717 assert_se(sigemptyset(&ss) == 0);
3718 assert_se(sigprocmask(SIG_SETMASK, &ss, NULL) == 0);
3720 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
3723 d = _d = opendir(directory);
3725 if (errno == ENOENT)
3726 _exit(EXIT_SUCCESS);
3728 log_error("Failed to enumerate directory %s: %m", directory);
3729 _exit(EXIT_FAILURE);
3733 pids = hashmap_new(NULL, NULL);
3736 _exit(EXIT_FAILURE);
3739 FOREACH_DIRENT(de, d, break) {
3740 _cleanup_free_ char *path = NULL;
3743 if (!dirent_is_file(de))
3746 if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
3748 _exit(EXIT_FAILURE);
3753 log_error("Failed to fork: %m");
3755 } else if (pid == 0) {
3758 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
3768 log_error("Failed to execute %s: %m", path);
3769 _exit(EXIT_FAILURE);
3773 log_debug("Spawned %s as " PID_FMT ".", path, pid);
3775 r = hashmap_put(pids, UINT_TO_PTR(pid), path);
3778 _exit(EXIT_FAILURE);
3784 /* Abort execution of this process after the
3785 * timout. We simply rely on SIGALRM as default action
3786 * terminating the process, and turn on alarm(). */
3788 if (timeout != (usec_t) -1)
3789 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
3791 while (!hashmap_isempty(pids)) {
3792 _cleanup_free_ char *path = NULL;
3795 pid = PTR_TO_UINT(hashmap_first_key(pids));
3798 path = hashmap_remove(pids, UINT_TO_PTR(pid));
3801 wait_for_terminate_and_warn(path, pid);
3804 _exit(EXIT_SUCCESS);
3807 wait_for_terminate_and_warn(directory, executor_pid);
3810 int kill_and_sigcont(pid_t pid, int sig) {
3813 r = kill(pid, sig) < 0 ? -errno : 0;
3821 bool nulstr_contains(const char*nulstr, const char *needle) {
3827 NULSTR_FOREACH(i, nulstr)
3828 if (streq(i, needle))
3834 bool plymouth_running(void) {
3835 return access("/run/plymouth/pid", F_OK) >= 0;
3838 char* strshorten(char *s, size_t l) {
3847 static bool hostname_valid_char(char c) {
3849 (c >= 'a' && c <= 'z') ||
3850 (c >= 'A' && c <= 'Z') ||
3851 (c >= '0' && c <= '9') ||
3857 bool hostname_is_valid(const char *s) {
3864 for (p = s, dot = true; *p; p++) {
3871 if (!hostname_valid_char(*p))
3881 if (p-s > HOST_NAME_MAX)
3887 char* hostname_cleanup(char *s, bool lowercase) {
3891 for (p = s, d = s, dot = true; *p; p++) {
3898 } else if (hostname_valid_char(*p)) {
3899 *(d++) = lowercase ? tolower(*p) : *p;
3910 strshorten(s, HOST_NAME_MAX);
3915 int pipe_eof(int fd) {
3916 struct pollfd pollfd = {
3918 .events = POLLIN|POLLHUP,
3923 r = poll(&pollfd, 1, 0);
3930 return pollfd.revents & POLLHUP;
3933 int fd_wait_for_event(int fd, int event, usec_t t) {
3935 struct pollfd pollfd = {
3943 r = ppoll(&pollfd, 1, t == (usec_t) -1 ? NULL : timespec_store(&ts, t), NULL);
3950 return pollfd.revents;
3953 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
3964 t = new(char, strlen(path) + 1 + 6 + 1);
3968 fn = basename(path);
3972 stpcpy(stpcpy(t+k+1, fn), "XXXXXX");
3974 fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
3980 f = fdopen(fd, "we");
3993 int terminal_vhangup_fd(int fd) {
3996 if (ioctl(fd, TIOCVHANGUP) < 0)
4002 int terminal_vhangup(const char *name) {
4005 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4009 r = terminal_vhangup_fd(fd);
4010 close_nointr_nofail(fd);
4015 int vt_disallocate(const char *name) {
4019 /* Deallocate the VT if possible. If not possible
4020 * (i.e. because it is the active one), at least clear it
4021 * entirely (including the scrollback buffer) */
4023 if (!startswith(name, "/dev/"))
4026 if (!tty_is_vc(name)) {
4027 /* So this is not a VT. I guess we cannot deallocate
4028 * it then. But let's at least clear the screen */
4030 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4035 "\033[r" /* clear scrolling region */
4036 "\033[H" /* move home */
4037 "\033[2J", /* clear screen */
4039 close_nointr_nofail(fd);
4044 if (!startswith(name, "/dev/tty"))
4047 r = safe_atou(name+8, &u);
4054 /* Try to deallocate */
4055 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
4059 r = ioctl(fd, VT_DISALLOCATE, u);
4060 close_nointr_nofail(fd);
4068 /* Couldn't deallocate, so let's clear it fully with
4070 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4075 "\033[r" /* clear scrolling region */
4076 "\033[H" /* move home */
4077 "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
4079 close_nointr_nofail(fd);
4084 int copy_file(const char *from, const char *to, int flags) {
4085 _cleanup_close_ int fdf = -1;
4091 fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
4095 fdt = open(to, flags|O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644);
4103 n = read(fdf, buf, sizeof(buf));
4117 k = loop_write(fdt, buf, n, false);
4119 r = k < 0 ? k : (errno ? -errno : -EIO);
4128 r = close_nointr(fdt);
4138 int symlink_atomic(const char *from, const char *to) {
4140 _cleanup_free_ char *t;
4150 t = new(char, strlen(to) + 1 + 16 + 1);
4158 x = stpcpy(t+k+1, fn);
4161 for (i = 0; i < 16; i++) {
4162 *(x++) = hexchar(u & 0xF);
4168 if (symlink(from, t) < 0)
4171 if (rename(t, to) < 0) {
4180 bool display_is_local(const char *display) {
4184 display[0] == ':' &&
4185 display[1] >= '0' &&
4189 int socket_from_display(const char *display, char **path) {
4196 if (!display_is_local(display))
4199 k = strspn(display+1, "0123456789");
4201 f = new(char, sizeof("/tmp/.X11-unix/X") + k);
4205 c = stpcpy(f, "/tmp/.X11-unix/X");
4206 memcpy(c, display+1, k);
4215 const char **username,
4216 uid_t *uid, gid_t *gid,
4218 const char **shell) {
4226 /* We enforce some special rules for uid=0: in order to avoid
4227 * NSS lookups for root we hardcode its data. */
4229 if (streq(*username, "root") || streq(*username, "0")) {
4247 if (parse_uid(*username, &u) >= 0) {
4251 /* If there are multiple users with the same id, make
4252 * sure to leave $USER to the configured value instead
4253 * of the first occurrence in the database. However if
4254 * the uid was configured by a numeric uid, then let's
4255 * pick the real username from /etc/passwd. */
4257 *username = p->pw_name;
4260 p = getpwnam(*username);
4264 return errno > 0 ? -errno : -ESRCH;
4276 *shell = p->pw_shell;
4281 char* uid_to_name(uid_t uid) {
4286 return strdup("root");
4290 return strdup(p->pw_name);
4292 if (asprintf(&r, "%lu", (unsigned long) uid) < 0)
4298 char* gid_to_name(gid_t gid) {
4303 return strdup("root");
4307 return strdup(p->gr_name);
4309 if (asprintf(&r, "%lu", (unsigned long) gid) < 0)
4315 int get_group_creds(const char **groupname, gid_t *gid) {
4321 /* We enforce some special rules for gid=0: in order to avoid
4322 * NSS lookups for root we hardcode its data. */
4324 if (streq(*groupname, "root") || streq(*groupname, "0")) {
4325 *groupname = "root";
4333 if (parse_gid(*groupname, &id) >= 0) {
4338 *groupname = g->gr_name;
4341 g = getgrnam(*groupname);
4345 return errno > 0 ? -errno : -ESRCH;
4353 int in_gid(gid_t gid) {
4355 int ngroups_max, r, i;
4357 if (getgid() == gid)
4360 if (getegid() == gid)
4363 ngroups_max = sysconf(_SC_NGROUPS_MAX);
4364 assert(ngroups_max > 0);
4366 gids = alloca(sizeof(gid_t) * ngroups_max);
4368 r = getgroups(ngroups_max, gids);
4372 for (i = 0; i < r; i++)
4379 int in_group(const char *name) {
4383 r = get_group_creds(&name, &gid);
4390 int glob_exists(const char *path) {
4391 _cleanup_globfree_ glob_t g = {};
4397 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
4399 if (k == GLOB_NOMATCH)
4401 else if (k == GLOB_NOSPACE)
4404 return !strv_isempty(g.gl_pathv);
4406 return errno ? -errno : -EIO;
4409 int glob_extend(char ***strv, const char *path) {
4410 _cleanup_globfree_ glob_t g = {};
4415 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
4417 if (k == GLOB_NOMATCH)
4419 else if (k == GLOB_NOSPACE)
4421 else if (k != 0 || strv_isempty(g.gl_pathv))
4422 return errno ? -errno : -EIO;
4424 STRV_FOREACH(p, g.gl_pathv) {
4425 k = strv_extend(strv, *p);
4433 int dirent_ensure_type(DIR *d, struct dirent *de) {
4439 if (de->d_type != DT_UNKNOWN)
4442 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
4446 S_ISREG(st.st_mode) ? DT_REG :
4447 S_ISDIR(st.st_mode) ? DT_DIR :
4448 S_ISLNK(st.st_mode) ? DT_LNK :
4449 S_ISFIFO(st.st_mode) ? DT_FIFO :
4450 S_ISSOCK(st.st_mode) ? DT_SOCK :
4451 S_ISCHR(st.st_mode) ? DT_CHR :
4452 S_ISBLK(st.st_mode) ? DT_BLK :
4458 int in_search_path(const char *path, char **search) {
4460 _cleanup_free_ char *parent = NULL;
4463 r = path_get_parent(path, &parent);
4467 STRV_FOREACH(i, search)
4468 if (path_equal(parent, *i))
4474 int get_files_in_directory(const char *path, char ***list) {
4475 _cleanup_closedir_ DIR *d = NULL;
4476 size_t bufsize = 0, n = 0;
4477 _cleanup_strv_free_ char **l = NULL;
4481 /* Returns all files in a directory in *list, and the number
4482 * of files as return value. If list is NULL returns only the
4494 if (!de && errno != 0)
4499 dirent_ensure_type(d, de);
4501 if (!dirent_is_file(de))
4505 /* one extra slot is needed for the terminating NULL */
4506 if (!GREEDY_REALLOC(l, bufsize, n + 2))
4509 l[n] = strdup(de->d_name);
4520 l = NULL; /* avoid freeing */
4526 char *strjoin(const char *x, ...) {
4540 t = va_arg(ap, const char *);
4545 if (n > ((size_t) -1) - l) {
4569 t = va_arg(ap, const char *);
4583 bool is_main_thread(void) {
4584 static thread_local int cached = 0;
4586 if (_unlikely_(cached == 0))
4587 cached = getpid() == gettid() ? 1 : -1;
4592 int block_get_whole_disk(dev_t d, dev_t *ret) {
4599 /* If it has a queue this is good enough for us */
4600 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
4603 r = access(p, F_OK);
4611 /* If it is a partition find the originating device */
4612 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
4615 r = access(p, F_OK);
4621 /* Get parent dev_t */
4622 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
4625 r = read_one_line_file(p, &s);
4631 r = sscanf(s, "%u:%u", &m, &n);
4637 /* Only return this if it is really good enough for us. */
4638 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
4641 r = access(p, F_OK);
4645 *ret = makedev(m, n);
4652 int file_is_priv_sticky(const char *p) {
4657 if (lstat(p, &st) < 0)
4661 (st.st_uid == 0 || st.st_uid == getuid()) &&
4662 (st.st_mode & S_ISVTX);
4665 static const char *const ioprio_class_table[] = {
4666 [IOPRIO_CLASS_NONE] = "none",
4667 [IOPRIO_CLASS_RT] = "realtime",
4668 [IOPRIO_CLASS_BE] = "best-effort",
4669 [IOPRIO_CLASS_IDLE] = "idle"
4672 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
4674 static const char *const sigchld_code_table[] = {
4675 [CLD_EXITED] = "exited",
4676 [CLD_KILLED] = "killed",
4677 [CLD_DUMPED] = "dumped",
4678 [CLD_TRAPPED] = "trapped",
4679 [CLD_STOPPED] = "stopped",
4680 [CLD_CONTINUED] = "continued",
4683 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
4685 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
4686 [LOG_FAC(LOG_KERN)] = "kern",
4687 [LOG_FAC(LOG_USER)] = "user",
4688 [LOG_FAC(LOG_MAIL)] = "mail",
4689 [LOG_FAC(LOG_DAEMON)] = "daemon",
4690 [LOG_FAC(LOG_AUTH)] = "auth",
4691 [LOG_FAC(LOG_SYSLOG)] = "syslog",
4692 [LOG_FAC(LOG_LPR)] = "lpr",
4693 [LOG_FAC(LOG_NEWS)] = "news",
4694 [LOG_FAC(LOG_UUCP)] = "uucp",
4695 [LOG_FAC(LOG_CRON)] = "cron",
4696 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
4697 [LOG_FAC(LOG_FTP)] = "ftp",
4698 [LOG_FAC(LOG_LOCAL0)] = "local0",
4699 [LOG_FAC(LOG_LOCAL1)] = "local1",
4700 [LOG_FAC(LOG_LOCAL2)] = "local2",
4701 [LOG_FAC(LOG_LOCAL3)] = "local3",
4702 [LOG_FAC(LOG_LOCAL4)] = "local4",
4703 [LOG_FAC(LOG_LOCAL5)] = "local5",
4704 [LOG_FAC(LOG_LOCAL6)] = "local6",
4705 [LOG_FAC(LOG_LOCAL7)] = "local7"
4708 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
4710 static const char *const log_level_table[] = {
4711 [LOG_EMERG] = "emerg",
4712 [LOG_ALERT] = "alert",
4713 [LOG_CRIT] = "crit",
4715 [LOG_WARNING] = "warning",
4716 [LOG_NOTICE] = "notice",
4717 [LOG_INFO] = "info",
4718 [LOG_DEBUG] = "debug"
4721 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
4723 static const char* const sched_policy_table[] = {
4724 [SCHED_OTHER] = "other",
4725 [SCHED_BATCH] = "batch",
4726 [SCHED_IDLE] = "idle",
4727 [SCHED_FIFO] = "fifo",
4731 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
4733 static const char* const rlimit_table[_RLIMIT_MAX] = {
4734 [RLIMIT_CPU] = "LimitCPU",
4735 [RLIMIT_FSIZE] = "LimitFSIZE",
4736 [RLIMIT_DATA] = "LimitDATA",
4737 [RLIMIT_STACK] = "LimitSTACK",
4738 [RLIMIT_CORE] = "LimitCORE",
4739 [RLIMIT_RSS] = "LimitRSS",
4740 [RLIMIT_NOFILE] = "LimitNOFILE",
4741 [RLIMIT_AS] = "LimitAS",
4742 [RLIMIT_NPROC] = "LimitNPROC",
4743 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
4744 [RLIMIT_LOCKS] = "LimitLOCKS",
4745 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
4746 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
4747 [RLIMIT_NICE] = "LimitNICE",
4748 [RLIMIT_RTPRIO] = "LimitRTPRIO",
4749 [RLIMIT_RTTIME] = "LimitRTTIME"
4752 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
4754 static const char* const ip_tos_table[] = {
4755 [IPTOS_LOWDELAY] = "low-delay",
4756 [IPTOS_THROUGHPUT] = "throughput",
4757 [IPTOS_RELIABILITY] = "reliability",
4758 [IPTOS_LOWCOST] = "low-cost",
4761 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
4763 static const char *const __signal_table[] = {
4780 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
4791 [SIGVTALRM] = "VTALRM",
4793 [SIGWINCH] = "WINCH",
4799 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
4801 const char *signal_to_string(int signo) {
4802 static thread_local char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1];
4805 name = __signal_to_string(signo);
4809 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
4810 snprintf(buf, sizeof(buf), "RTMIN+%d", signo - SIGRTMIN);
4812 snprintf(buf, sizeof(buf), "%d", signo);
4817 int signal_from_string(const char *s) {
4822 signo = __signal_from_string(s);
4826 if (startswith(s, "RTMIN+")) {
4830 if (safe_atou(s, &u) >= 0) {
4831 signo = (int) u + offset;
4832 if (signo > 0 && signo < _NSIG)
4838 bool kexec_loaded(void) {
4839 bool loaded = false;
4842 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
4850 int strdup_or_null(const char *a, char **b) {
4868 int prot_from_flags(int flags) {
4870 switch (flags & O_ACCMODE) {
4879 return PROT_READ|PROT_WRITE;
4886 char *format_bytes(char *buf, size_t l, off_t t) {
4889 static const struct {
4893 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
4894 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
4895 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
4896 { "G", 1024ULL*1024ULL*1024ULL },
4897 { "M", 1024ULL*1024ULL },
4901 for (i = 0; i < ELEMENTSOF(table); i++) {
4903 if (t >= table[i].factor) {
4906 (unsigned long long) (t / table[i].factor),
4907 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
4914 snprintf(buf, l, "%lluB", (unsigned long long) t);
4922 void* memdup(const void *p, size_t l) {
4935 int fd_inc_sndbuf(int fd, size_t n) {
4937 socklen_t l = sizeof(value);
4939 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
4940 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
4943 /* If we have the privileges we will ignore the kernel limit. */
4946 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
4947 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
4953 int fd_inc_rcvbuf(int fd, size_t n) {
4955 socklen_t l = sizeof(value);
4957 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
4958 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
4961 /* If we have the privileges we will ignore the kernel limit. */
4964 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
4965 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
4970 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
4971 pid_t parent_pid, agent_pid;
4973 bool stdout_is_tty, stderr_is_tty;
4981 parent_pid = getpid();
4983 /* Spawns a temporary TTY agent, making sure it goes away when
4990 if (agent_pid != 0) {
4997 * Make sure the agent goes away when the parent dies */
4998 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
4999 _exit(EXIT_FAILURE);
5001 /* Check whether our parent died before we were able
5002 * to set the death signal */
5003 if (getppid() != parent_pid)
5004 _exit(EXIT_SUCCESS);
5006 /* Don't leak fds to the agent */
5007 close_all_fds(except, n_except);
5009 stdout_is_tty = isatty(STDOUT_FILENO);
5010 stderr_is_tty = isatty(STDERR_FILENO);
5012 if (!stdout_is_tty || !stderr_is_tty) {
5013 /* Detach from stdout/stderr. and reopen
5014 * /dev/tty for them. This is important to
5015 * ensure that when systemctl is started via
5016 * popen() or a similar call that expects to
5017 * read EOF we actually do generate EOF and
5018 * not delay this indefinitely by because we
5019 * keep an unused copy of stdin around. */
5020 fd = open("/dev/tty", O_WRONLY);
5022 log_error("Failed to open /dev/tty: %m");
5023 _exit(EXIT_FAILURE);
5027 dup2(fd, STDOUT_FILENO);
5030 dup2(fd, STDERR_FILENO);
5036 /* Count arguments */
5038 for (n = 0; va_arg(ap, char*); n++)
5043 l = alloca(sizeof(char *) * (n + 1));
5045 /* Fill in arguments */
5047 for (i = 0; i <= n; i++)
5048 l[i] = va_arg(ap, char*);
5052 _exit(EXIT_FAILURE);
5055 int setrlimit_closest(int resource, const struct rlimit *rlim) {
5056 struct rlimit highest, fixed;
5060 if (setrlimit(resource, rlim) >= 0)
5066 /* So we failed to set the desired setrlimit, then let's try
5067 * to get as close as we can */
5068 assert_se(getrlimit(resource, &highest) == 0);
5070 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
5071 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
5073 if (setrlimit(resource, &fixed) < 0)
5079 int getenv_for_pid(pid_t pid, const char *field, char **_value) {
5080 _cleanup_fclose_ FILE *f = NULL;
5091 path = procfs_file_alloca(pid, "environ");
5093 f = fopen(path, "re");
5101 char line[LINE_MAX];
5104 for (i = 0; i < sizeof(line)-1; i++) {
5108 if (_unlikely_(c == EOF)) {
5118 if (memcmp(line, field, l) == 0 && line[l] == '=') {
5119 value = strdup(line + l + 1);
5133 bool is_valid_documentation_url(const char *url) {
5136 if (startswith(url, "http://") && url[7])
5139 if (startswith(url, "https://") && url[8])
5142 if (startswith(url, "file:") && url[5])
5145 if (startswith(url, "info:") && url[5])
5148 if (startswith(url, "man:") && url[4])
5154 bool in_initrd(void) {
5155 static int saved = -1;
5161 /* We make two checks here:
5163 * 1. the flag file /etc/initrd-release must exist
5164 * 2. the root file system must be a memory file system
5166 * The second check is extra paranoia, since misdetecting an
5167 * initrd can have bad bad consequences due the initrd
5168 * emptying when transititioning to the main systemd.
5171 saved = access("/etc/initrd-release", F_OK) >= 0 &&
5172 statfs("/", &s) >= 0 &&
5173 is_temporary_fs(&s);
5178 void warn_melody(void) {
5179 _cleanup_close_ int fd = -1;
5181 fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
5185 /* Yeah, this is synchronous. Kinda sucks. But well... */
5187 ioctl(fd, KIOCSOUND, (int)(1193180/440));
5188 usleep(125*USEC_PER_MSEC);
5190 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5191 usleep(125*USEC_PER_MSEC);
5193 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5194 usleep(125*USEC_PER_MSEC);
5196 ioctl(fd, KIOCSOUND, 0);
5199 int make_console_stdio(void) {
5202 /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
5204 fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1);
5206 log_error("Failed to acquire terminal: %s", strerror(-fd));
5212 log_error("Failed to duplicate terminal fd: %s", strerror(-r));
5219 int get_home_dir(char **_h) {
5227 /* Take the user specified one */
5238 /* Hardcode home directory for root to avoid NSS */
5241 h = strdup("/root");
5249 /* Check the database... */
5253 return errno > 0 ? -errno : -ESRCH;
5255 if (!path_is_absolute(p->pw_dir))
5258 h = strdup(p->pw_dir);
5266 int get_shell(char **_s) {
5274 /* Take the user specified one */
5275 e = getenv("SHELL");
5285 /* Hardcode home directory for root to avoid NSS */
5288 s = strdup("/bin/sh");
5296 /* Check the database... */
5300 return errno > 0 ? -errno : -ESRCH;
5302 if (!path_is_absolute(p->pw_shell))
5305 s = strdup(p->pw_shell);
5313 bool filename_is_safe(const char *p) {
5327 if (strlen(p) > FILENAME_MAX)
5333 bool string_is_safe(const char *p) {
5338 for (t = p; *t; t++) {
5339 if (*t > 0 && *t < ' ')
5342 if (strchr("\\\"\'", *t))
5350 * Check if a string contains control characters.
5351 * Spaces and tabs are not considered control characters.
5353 bool string_has_cc(const char *p) {
5358 for (t = p; *t; t++)
5359 if (*t > 0 && *t < ' ' && *t != '\t')
5365 bool path_is_safe(const char *p) {
5370 if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
5373 if (strlen(p) > PATH_MAX)
5376 /* The following two checks are not really dangerous, but hey, they still are confusing */
5377 if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
5380 if (strstr(p, "//"))
5386 /* hey glibc, APIs with callbacks without a user pointer are so useless */
5387 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
5388 int (*compar) (const void *, const void *, void *), void *arg) {
5397 p = (void *)(((const char *) base) + (idx * size));
5398 comparison = compar(key, p, arg);
5401 else if (comparison > 0)
5409 bool is_locale_utf8(void) {
5411 static int cached_answer = -1;
5413 if (cached_answer >= 0)
5416 if (!setlocale(LC_ALL, "")) {
5417 cached_answer = true;
5421 set = nl_langinfo(CODESET);
5423 cached_answer = true;
5427 if (streq(set, "UTF-8")) {
5428 cached_answer = true;
5432 /* For LC_CTYPE=="C" return true, because CTYPE is effectly
5433 * unset and everything can do to UTF-8 nowadays. */
5434 set = setlocale(LC_CTYPE, NULL);
5436 cached_answer = true;
5440 /* Check result, but ignore the result if C was set
5444 !getenv("LC_ALL") &&
5445 !getenv("LC_CTYPE") &&
5449 return (bool) cached_answer;
5452 const char *draw_special_char(DrawSpecialChar ch) {
5453 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
5455 [DRAW_TREE_VERT] = "\342\224\202 ", /* │ */
5456 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
5457 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
5458 [DRAW_TREE_SPACE] = " ", /* */
5459 [DRAW_TRIANGULAR_BULLET] = "\342\200\243 ", /* ‣ */
5460 [DRAW_BLACK_CIRCLE] = "\342\227\217 ", /* ● */
5462 /* ASCII fallback */ {
5463 [DRAW_TREE_VERT] = "| ",
5464 [DRAW_TREE_BRANCH] = "|-",
5465 [DRAW_TREE_RIGHT] = "`-",
5466 [DRAW_TREE_SPACE] = " ",
5467 [DRAW_TRIANGULAR_BULLET] = "> ",
5468 [DRAW_BLACK_CIRCLE] = "* ",
5472 return draw_table[!is_locale_utf8()][ch];
5475 char *strreplace(const char *text, const char *old_string, const char *new_string) {
5478 size_t l, old_len, new_len;
5484 old_len = strlen(old_string);
5485 new_len = strlen(new_string);
5498 if (!startswith(f, old_string)) {
5504 nl = l - old_len + new_len;
5505 a = realloc(r, nl + 1);
5513 t = stpcpy(t, new_string);
5525 char *strip_tab_ansi(char **ibuf, size_t *_isz) {
5526 const char *i, *begin = NULL;
5531 } state = STATE_OTHER;
5533 size_t osz = 0, isz;
5539 /* Strips ANSI color and replaces TABs by 8 spaces */
5541 isz = _isz ? *_isz : strlen(*ibuf);
5543 f = open_memstream(&obuf, &osz);
5547 for (i = *ibuf; i < *ibuf + isz + 1; i++) {
5552 if (i >= *ibuf + isz) /* EOT */
5554 else if (*i == '\x1B')
5555 state = STATE_ESCAPE;
5556 else if (*i == '\t')
5563 if (i >= *ibuf + isz) { /* EOT */
5566 } else if (*i == '[') {
5567 state = STATE_BRACKET;
5572 state = STATE_OTHER;
5579 if (i >= *ibuf + isz || /* EOT */
5580 (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
5583 state = STATE_OTHER;
5585 } else if (*i == 'm')
5586 state = STATE_OTHER;
5608 int on_ac_power(void) {
5609 bool found_offline = false, found_online = false;
5610 _cleanup_closedir_ DIR *d = NULL;
5612 d = opendir("/sys/class/power_supply");
5618 _cleanup_close_ int fd = -1, device = -1;
5624 if (!de && errno != 0)
5630 if (ignore_file(de->d_name))
5633 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
5635 if (errno == ENOENT || errno == ENOTDIR)
5641 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
5643 if (errno == ENOENT)
5649 n = read(fd, contents, sizeof(contents));
5653 if (n != 6 || memcmp(contents, "Mains\n", 6))
5656 close_nointr_nofail(fd);
5657 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
5659 if (errno == ENOENT)
5665 n = read(fd, contents, sizeof(contents));
5669 if (n != 2 || contents[1] != '\n')
5672 if (contents[0] == '1') {
5673 found_online = true;
5675 } else if (contents[0] == '0')
5676 found_offline = true;
5681 return found_online || !found_offline;
5684 static int search_and_fopen_internal(const char *path, const char *mode, char **search, FILE **_f) {
5691 if (!path_strv_canonicalize_absolute_uniq(search, NULL))
5694 STRV_FOREACH(i, search) {
5695 _cleanup_free_ char *p = NULL;
5698 p = strjoin(*i, "/", path, NULL);
5708 if (errno != ENOENT)
5715 int search_and_fopen(const char *path, const char *mode, const char **search, FILE **_f) {
5716 _cleanup_strv_free_ char **copy = NULL;
5722 if (path_is_absolute(path)) {
5725 f = fopen(path, mode);
5734 copy = strv_copy((char**) search);
5738 return search_and_fopen_internal(path, mode, copy, _f);
5741 int search_and_fopen_nulstr(const char *path, const char *mode, const char *search, FILE **_f) {
5742 _cleanup_strv_free_ char **s = NULL;
5744 if (path_is_absolute(path)) {
5747 f = fopen(path, mode);
5756 s = strv_split_nulstr(search);
5760 return search_and_fopen_internal(path, mode, s, _f);
5763 char *strextend(char **x, ...) {
5770 l = f = *x ? strlen(*x) : 0;
5777 t = va_arg(ap, const char *);
5782 if (n > ((size_t) -1) - l) {
5791 r = realloc(*x, l+1);
5801 t = va_arg(ap, const char *);
5815 char *strrep(const char *s, unsigned n) {
5823 p = r = malloc(l * n + 1);
5827 for (i = 0; i < n; i++)
5834 void* greedy_realloc(void **p, size_t *allocated, size_t need) {
5841 if (*allocated >= need)
5844 a = MAX(64u, need * 2);
5846 /* check for overflows */
5859 void* greedy_realloc0(void **p, size_t *allocated, size_t need) {
5868 q = greedy_realloc(p, allocated, need);
5872 if (*allocated > prev)
5873 memzero(&q[prev], *allocated - prev);
5878 bool id128_is_valid(const char *s) {
5884 /* Simple formatted 128bit hex string */
5886 for (i = 0; i < l; i++) {
5889 if (!(c >= '0' && c <= '9') &&
5890 !(c >= 'a' && c <= 'z') &&
5891 !(c >= 'A' && c <= 'Z'))
5895 } else if (l == 36) {
5897 /* Formatted UUID */
5899 for (i = 0; i < l; i++) {
5902 if ((i == 8 || i == 13 || i == 18 || i == 23)) {
5906 if (!(c >= '0' && c <= '9') &&
5907 !(c >= 'a' && c <= 'z') &&
5908 !(c >= 'A' && c <= 'Z'))
5919 int split_pair(const char *s, const char *sep, char **l, char **r) {
5934 a = strndup(s, x - s);
5938 b = strdup(x + strlen(sep));
5950 int shall_restore_state(void) {
5951 _cleanup_free_ char *line = NULL;
5956 r = proc_cmdline(&line);
5959 if (r == 0) /* Container ... */
5964 FOREACH_WORD_QUOTED(w, l, line, state) {
5972 e = startswith(n, "systemd.restore_state=");
5976 k = parse_boolean(e);
5984 int proc_cmdline(char **ret) {
5987 if (detect_container(NULL) > 0) {
5988 char *buf = NULL, *p;
5991 r = read_full_file("/proc/1/cmdline", &buf, &sz);
5995 for (p = buf; p + 1 < buf + sz; p++)
6004 r = read_one_line_file("/proc/cmdline", ret);
6011 int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
6012 _cleanup_free_ char *line = NULL;
6019 r = proc_cmdline(&line);
6021 log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
6025 FOREACH_WORD_QUOTED(w, l, line, state) {
6026 char word[l+1], *value;
6031 /* Filter out arguments that are intended only for the
6033 if (!in_initrd() && startswith(word, "rd."))
6036 value = strchr(word, '=');
6040 r = parse_item(word, value);
6048 int container_get_leader(const char *machine, pid_t *pid) {
6049 _cleanup_free_ char *s = NULL, *class = NULL;
6057 p = strappenda("/run/systemd/machines/", machine);
6058 r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
6066 if (!streq_ptr(class, "container"))
6069 r = parse_pid(s, &leader);
6079 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *root_fd) {
6080 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1;
6081 const char *pidns, *mntns, *root;
6089 mntns = procfs_file_alloca(pid, "ns/mnt");
6090 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
6094 pidns = procfs_file_alloca(pid, "ns/pid");
6095 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
6099 root = procfs_file_alloca(pid, "root");
6100 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
6104 *pidns_fd = pidnsfd;
6105 *mntns_fd = mntnsfd;
6113 int namespace_enter(int pidns_fd, int mntns_fd, int root_fd) {
6114 assert(pidns_fd >= 0);
6115 assert(mntns_fd >= 0);
6116 assert(root_fd >= 0);
6118 if (setns(pidns_fd, CLONE_NEWPID) < 0)
6121 if (setns(mntns_fd, CLONE_NEWNS) < 0)
6124 if (fchdir(root_fd) < 0)
6127 if (chroot(".") < 0)
6130 if (setresgid(0, 0, 0) < 0)
6133 if (setresuid(0, 0, 0) < 0)
6139 bool pid_is_unwaited(pid_t pid) {
6140 /* Checks whether a PID is still valid at all, including a zombie */
6145 if (kill(pid, 0) >= 0)
6148 return errno != ESRCH;
6151 bool pid_is_alive(pid_t pid) {
6154 /* Checks whether a PID is still valid and not a zombie */
6159 r = get_process_state(pid);
6160 if (r == -ENOENT || r == 'Z')
6166 int getpeercred(int fd, struct ucred *ucred) {
6167 socklen_t n = sizeof(struct ucred);
6174 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
6178 if (n != sizeof(struct ucred))
6181 /* Check if the data is actually useful and not suppressed due
6182 * to namespacing issues */
6190 int getpeersec(int fd, char **ret) {
6202 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
6206 if (errno != ERANGE)
6213 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
6229 /* This is much like like mkostemp() but is subject to umask(). */
6230 int mkostemp_safe(char *pattern, int flags) {
6231 _cleanup_umask_ mode_t u;
6238 fd = mkostemp(pattern, flags);
6245 int open_tmpfile(const char *path, int flags) {
6252 /* Try O_TMPFILE first, if it is supported */
6253 fd = open(path, flags|O_TMPFILE, S_IRUSR|S_IWUSR);
6258 /* Fall back to unguessable name + unlinking */
6259 p = strappenda(path, "/systemd-tmp-XXXXXX");
6261 fd = mkostemp_safe(p, flags);
6269 int fd_warn_permissions(const char *path, int fd) {
6272 if (fstat(fd, &st) < 0)
6275 if (st.st_mode & 0111)
6276 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
6278 if (st.st_mode & 0002)
6279 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
6281 if (getpid() == 1 && (st.st_mode & 0044) != 0044)
6282 log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path);
6287 unsigned long personality_from_string(const char *p) {
6289 /* Parse a personality specifier. We introduce our own
6290 * identifiers that indicate specific ABIs, rather than just
6291 * hints regarding the register size, since we want to keep
6292 * things open for multiple locally supported ABIs for the
6293 * same register size. We try to reuse the ABI identifiers
6294 * used by libseccomp. */
6296 #if defined(__x86_64__)
6298 if (streq(p, "x86"))
6301 if (streq(p, "x86-64"))
6304 #elif defined(__i386__)
6306 if (streq(p, "x86"))
6310 /* personality(7) documents that 0xffffffffUL is used for
6311 * querying the current personality, hence let's use that here
6312 * as error indicator. */
6313 return 0xffffffffUL;
6316 const char* personality_to_string(unsigned long p) {
6318 #if defined(__x86_64__)
6320 if (p == PER_LINUX32)
6326 #elif defined(__i386__)
6335 uint64_t physical_memory(void) {
6338 /* We return this as uint64_t in case we are running as 32bit
6339 * process on a 64bit kernel with huge amounts of memory */
6341 mem = sysconf(_SC_PHYS_PAGES);
6344 return (uint64_t) mem * (uint64_t) page_size();
6347 char* mount_test_option(const char *haystack, const char *needle) {
6349 struct mntent me = {
6350 .mnt_opts = (char*) haystack
6355 /* Like glibc's hasmntopt(), but works on a string, not a
6361 return hasmntopt(&me, needle);