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) {
926 return s[strspn(s, charset)] == '\0';
929 char *file_in_same_dir(const char *path, const char *filename) {
936 /* This removes the last component of path and appends
937 * filename, unless the latter is absolute anyway or the
940 if (path_is_absolute(filename))
941 return strdup(filename);
943 if (!(e = strrchr(path, '/')))
944 return strdup(filename);
946 k = strlen(filename);
947 if (!(r = new(char, e-path+1+k+1)))
950 memcpy(r, path, e-path+1);
951 memcpy(r+(e-path)+1, filename, k+1);
956 int rmdir_parents(const char *path, const char *stop) {
965 /* Skip trailing slashes */
966 while (l > 0 && path[l-1] == '/')
972 /* Skip last component */
973 while (l > 0 && path[l-1] != '/')
976 /* Skip trailing slashes */
977 while (l > 0 && path[l-1] == '/')
983 if (!(t = strndup(path, l)))
986 if (path_startswith(stop, t)) {
1002 char hexchar(int x) {
1003 static const char table[16] = "0123456789abcdef";
1005 return table[x & 15];
1008 int unhexchar(char c) {
1010 if (c >= '0' && c <= '9')
1013 if (c >= 'a' && c <= 'f')
1014 return c - 'a' + 10;
1016 if (c >= 'A' && c <= 'F')
1017 return c - 'A' + 10;
1022 char *hexmem(const void *p, size_t l) {
1026 z = r = malloc(l * 2 + 1);
1030 for (x = p; x < (const uint8_t*) p + l; x++) {
1031 *(z++) = hexchar(*x >> 4);
1032 *(z++) = hexchar(*x & 15);
1039 void *unhexmem(const char *p, size_t l) {
1045 z = r = malloc((l + 1) / 2 + 1);
1049 for (x = p; x < p + l; x += 2) {
1052 a = unhexchar(x[0]);
1054 b = unhexchar(x[1]);
1058 *(z++) = (uint8_t) a << 4 | (uint8_t) b;
1065 char octchar(int x) {
1066 return '0' + (x & 7);
1069 int unoctchar(char c) {
1071 if (c >= '0' && c <= '7')
1077 char decchar(int x) {
1078 return '0' + (x % 10);
1081 int undecchar(char c) {
1083 if (c >= '0' && c <= '9')
1089 char *cescape(const char *s) {
1095 /* Does C style string escaping. */
1097 r = new(char, strlen(s)*4 + 1);
1101 for (f = s, t = r; *f; f++)
1147 /* For special chars we prefer octal over
1148 * hexadecimal encoding, simply because glib's
1149 * g_strescape() does the same */
1150 if ((*f < ' ') || (*f >= 127)) {
1152 *(t++) = octchar((unsigned char) *f >> 6);
1153 *(t++) = octchar((unsigned char) *f >> 3);
1154 *(t++) = octchar((unsigned char) *f);
1165 char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix) {
1172 /* Undoes C style string escaping, and optionally prefixes it. */
1174 pl = prefix ? strlen(prefix) : 0;
1176 r = new(char, pl+length+1);
1181 memcpy(r, prefix, pl);
1183 for (f = s, t = r + pl; f < s + length; f++) {
1226 /* This is an extension of the XDG syntax files */
1231 /* hexadecimal encoding */
1234 a = unhexchar(f[1]);
1235 b = unhexchar(f[2]);
1237 if (a < 0 || b < 0) {
1238 /* Invalid escape code, let's take it literal then */
1242 *(t++) = (char) ((a << 4) | b);
1257 /* octal encoding */
1260 a = unoctchar(f[0]);
1261 b = unoctchar(f[1]);
1262 c = unoctchar(f[2]);
1264 if (a < 0 || b < 0 || c < 0) {
1265 /* Invalid escape code, let's take it literal then */
1269 *(t++) = (char) ((a << 6) | (b << 3) | c);
1277 /* premature end of string.*/
1282 /* Invalid escape code, let's take it literal then */
1294 char *cunescape_length(const char *s, size_t length) {
1295 return cunescape_length_with_prefix(s, length, NULL);
1298 char *cunescape(const char *s) {
1301 return cunescape_length(s, strlen(s));
1304 char *xescape(const char *s, const char *bad) {
1308 /* Escapes all chars in bad, in addition to \ and all special
1309 * chars, in \xFF style escaping. May be reversed with
1312 r = new(char, strlen(s) * 4 + 1);
1316 for (f = s, t = r; *f; f++) {
1318 if ((*f < ' ') || (*f >= 127) ||
1319 (*f == '\\') || strchr(bad, *f)) {
1322 *(t++) = hexchar(*f >> 4);
1323 *(t++) = hexchar(*f);
1333 char *ascii_strlower(char *t) {
1338 for (p = t; *p; p++)
1339 if (*p >= 'A' && *p <= 'Z')
1340 *p = *p - 'A' + 'a';
1345 _pure_ static bool ignore_file_allow_backup(const char *filename) {
1349 filename[0] == '.' ||
1350 streq(filename, "lost+found") ||
1351 streq(filename, "aquota.user") ||
1352 streq(filename, "aquota.group") ||
1353 endswith(filename, ".rpmnew") ||
1354 endswith(filename, ".rpmsave") ||
1355 endswith(filename, ".rpmorig") ||
1356 endswith(filename, ".dpkg-old") ||
1357 endswith(filename, ".dpkg-new") ||
1358 endswith(filename, ".swp");
1361 bool ignore_file(const char *filename) {
1364 if (endswith(filename, "~"))
1367 return ignore_file_allow_backup(filename);
1370 int fd_nonblock(int fd, bool nonblock) {
1375 if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
1379 flags |= O_NONBLOCK;
1381 flags &= ~O_NONBLOCK;
1383 if (fcntl(fd, F_SETFL, flags) < 0)
1389 int fd_cloexec(int fd, bool cloexec) {
1394 if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
1398 flags |= FD_CLOEXEC;
1400 flags &= ~FD_CLOEXEC;
1402 if (fcntl(fd, F_SETFD, flags) < 0)
1408 _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
1411 assert(n_fdset == 0 || fdset);
1413 for (i = 0; i < n_fdset; i++)
1420 int close_all_fds(const int except[], unsigned n_except) {
1425 assert(n_except == 0 || except);
1427 d = opendir("/proc/self/fd");
1432 /* When /proc isn't available (for example in chroots)
1433 * the fallback is brute forcing through the fd
1436 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
1437 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
1439 if (fd_in_set(fd, except, n_except))
1442 if (close_nointr(fd) < 0)
1443 if (errno != EBADF && r == 0)
1450 while ((de = readdir(d))) {
1453 if (ignore_file(de->d_name))
1456 if (safe_atoi(de->d_name, &fd) < 0)
1457 /* Let's better ignore this, just in case */
1466 if (fd_in_set(fd, except, n_except))
1469 if (close_nointr(fd) < 0) {
1470 /* Valgrind has its own FD and doesn't want to have it closed */
1471 if (errno != EBADF && r == 0)
1480 bool chars_intersect(const char *a, const char *b) {
1483 /* Returns true if any of the chars in a are in b. */
1484 for (p = a; *p; p++)
1491 bool fstype_is_network(const char *fstype) {
1492 static const char table[] =
1502 return nulstr_contains(table, fstype);
1506 _cleanup_close_ int fd;
1508 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
1514 TIOCL_GETKMSGREDIRECT,
1518 if (ioctl(fd, TIOCLINUX, tiocl) < 0)
1521 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
1524 if (ioctl(fd, VT_ACTIVATE, vt) < 0)
1530 int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
1531 struct termios old_termios, new_termios;
1533 char line[LINE_MAX];
1538 if (tcgetattr(fileno(f), &old_termios) >= 0) {
1539 new_termios = old_termios;
1541 new_termios.c_lflag &= ~ICANON;
1542 new_termios.c_cc[VMIN] = 1;
1543 new_termios.c_cc[VTIME] = 0;
1545 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
1548 if (t != (usec_t) -1) {
1549 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
1550 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
1555 k = fread(&c, 1, 1, f);
1557 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
1563 *need_nl = c != '\n';
1570 if (t != (usec_t) -1)
1571 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
1574 if (!fgets(line, sizeof(line), f))
1579 if (strlen(line) != 1)
1589 int ask(char *ret, const char *replies, const char *text, ...) {
1599 bool need_nl = true;
1602 fputs(ANSI_HIGHLIGHT_ON, stdout);
1609 fputs(ANSI_HIGHLIGHT_OFF, stdout);
1613 r = read_one_char(stdin, &c, (usec_t) -1, &need_nl);
1616 if (r == -EBADMSG) {
1617 puts("Bad input, please try again.");
1628 if (strchr(replies, c)) {
1633 puts("Read unexpected character, please try again.");
1637 int reset_terminal_fd(int fd, bool switch_to_text) {
1638 struct termios termios;
1641 /* Set terminal to some sane defaults */
1645 /* We leave locked terminal attributes untouched, so that
1646 * Plymouth may set whatever it wants to set, and we don't
1647 * interfere with that. */
1649 /* Disable exclusive mode, just in case */
1650 ioctl(fd, TIOCNXCL);
1652 /* Switch to text mode */
1654 ioctl(fd, KDSETMODE, KD_TEXT);
1656 /* Enable console unicode mode */
1657 ioctl(fd, KDSKBMODE, K_UNICODE);
1659 if (tcgetattr(fd, &termios) < 0) {
1664 /* We only reset the stuff that matters to the software. How
1665 * hardware is set up we don't touch assuming that somebody
1666 * else will do that for us */
1668 termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
1669 termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
1670 termios.c_oflag |= ONLCR;
1671 termios.c_cflag |= CREAD;
1672 termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
1674 termios.c_cc[VINTR] = 03; /* ^C */
1675 termios.c_cc[VQUIT] = 034; /* ^\ */
1676 termios.c_cc[VERASE] = 0177;
1677 termios.c_cc[VKILL] = 025; /* ^X */
1678 termios.c_cc[VEOF] = 04; /* ^D */
1679 termios.c_cc[VSTART] = 021; /* ^Q */
1680 termios.c_cc[VSTOP] = 023; /* ^S */
1681 termios.c_cc[VSUSP] = 032; /* ^Z */
1682 termios.c_cc[VLNEXT] = 026; /* ^V */
1683 termios.c_cc[VWERASE] = 027; /* ^W */
1684 termios.c_cc[VREPRINT] = 022; /* ^R */
1685 termios.c_cc[VEOL] = 0;
1686 termios.c_cc[VEOL2] = 0;
1688 termios.c_cc[VTIME] = 0;
1689 termios.c_cc[VMIN] = 1;
1691 if (tcsetattr(fd, TCSANOW, &termios) < 0)
1695 /* Just in case, flush all crap out */
1696 tcflush(fd, TCIOFLUSH);
1701 int reset_terminal(const char *name) {
1704 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
1708 r = reset_terminal_fd(fd, true);
1709 close_nointr_nofail(fd);
1714 int open_terminal(const char *name, int mode) {
1719 * If a TTY is in the process of being closed opening it might
1720 * cause EIO. This is horribly awful, but unlikely to be
1721 * changed in the kernel. Hence we work around this problem by
1722 * retrying a couple of times.
1724 * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
1727 assert(!(mode & O_CREAT));
1730 fd = open(name, mode, 0);
1737 /* Max 1s in total */
1741 usleep(50 * USEC_PER_MSEC);
1750 close_nointr_nofail(fd);
1755 close_nointr_nofail(fd);
1762 int flush_fd(int fd) {
1763 struct pollfd pollfd = {
1773 r = poll(&pollfd, 1, 0);
1783 l = read(fd, buf, sizeof(buf));
1789 if (errno == EAGAIN)
1798 int acquire_terminal(
1802 bool ignore_tiocstty_eperm,
1805 int fd = -1, notify = -1, r = 0, wd = -1;
1810 /* We use inotify to be notified when the tty is closed. We
1811 * create the watch before checking if we can actually acquire
1812 * it, so that we don't lose any event.
1814 * Note: strictly speaking this actually watches for the
1815 * device being closed, it does *not* really watch whether a
1816 * tty loses its controlling process. However, unless some
1817 * rogue process uses TIOCNOTTY on /dev/tty *after* closing
1818 * its tty otherwise this will not become a problem. As long
1819 * as the administrator makes sure not configure any service
1820 * on the same tty as an untrusted user this should not be a
1821 * problem. (Which he probably should not do anyway.) */
1823 if (timeout != (usec_t) -1)
1824 ts = now(CLOCK_MONOTONIC);
1826 if (!fail && !force) {
1827 notify = inotify_init1(IN_CLOEXEC | (timeout != (usec_t) -1 ? IN_NONBLOCK : 0));
1833 wd = inotify_add_watch(notify, name, IN_CLOSE);
1841 struct sigaction sa_old, sa_new = {
1842 .sa_handler = SIG_IGN,
1843 .sa_flags = SA_RESTART,
1847 r = flush_fd(notify);
1852 /* We pass here O_NOCTTY only so that we can check the return
1853 * value TIOCSCTTY and have a reliable way to figure out if we
1854 * successfully became the controlling process of the tty */
1855 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
1859 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
1860 * if we already own the tty. */
1861 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
1863 /* First, try to get the tty */
1864 if (ioctl(fd, TIOCSCTTY, force) < 0)
1867 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
1869 /* Sometimes it makes sense to ignore TIOCSCTTY
1870 * returning EPERM, i.e. when very likely we already
1871 * are have this controlling terminal. */
1872 if (r < 0 && r == -EPERM && ignore_tiocstty_eperm)
1875 if (r < 0 && (force || fail || r != -EPERM)) {
1884 assert(notify >= 0);
1887 uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
1889 struct inotify_event *e;
1891 if (timeout != (usec_t) -1) {
1894 n = now(CLOCK_MONOTONIC);
1895 if (ts + timeout < n) {
1900 r = fd_wait_for_event(fd, POLLIN, ts + timeout - n);
1910 l = read(notify, inotify_buffer, sizeof(inotify_buffer));
1913 if (errno == EINTR || errno == EAGAIN)
1920 e = (struct inotify_event*) inotify_buffer;
1925 if (e->wd != wd || !(e->mask & IN_CLOSE)) {
1930 step = sizeof(struct inotify_event) + e->len;
1931 assert(step <= (size_t) l);
1933 e = (struct inotify_event*) ((uint8_t*) e + step);
1940 /* We close the tty fd here since if the old session
1941 * ended our handle will be dead. It's important that
1942 * we do this after sleeping, so that we don't enter
1943 * an endless loop. */
1944 close_nointr_nofail(fd);
1948 close_nointr_nofail(notify);
1950 r = reset_terminal_fd(fd, true);
1952 log_warning("Failed to reset terminal: %s", strerror(-r));
1958 close_nointr_nofail(fd);
1961 close_nointr_nofail(notify);
1966 int release_terminal(void) {
1968 struct sigaction sa_old, sa_new = {
1969 .sa_handler = SIG_IGN,
1970 .sa_flags = SA_RESTART,
1972 _cleanup_close_ int fd;
1974 fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC);
1978 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
1979 * by our own TIOCNOTTY */
1980 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
1982 if (ioctl(fd, TIOCNOTTY) < 0)
1985 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
1990 int sigaction_many(const struct sigaction *sa, ...) {
1995 while ((sig = va_arg(ap, int)) > 0)
1996 if (sigaction(sig, sa, NULL) < 0)
2003 int ignore_signals(int sig, ...) {
2004 struct sigaction sa = {
2005 .sa_handler = SIG_IGN,
2006 .sa_flags = SA_RESTART,
2012 if (sigaction(sig, &sa, NULL) < 0)
2016 while ((sig = va_arg(ap, int)) > 0)
2017 if (sigaction(sig, &sa, NULL) < 0)
2024 int default_signals(int sig, ...) {
2025 struct sigaction sa = {
2026 .sa_handler = SIG_DFL,
2027 .sa_flags = SA_RESTART,
2032 if (sigaction(sig, &sa, NULL) < 0)
2036 while ((sig = va_arg(ap, int)) > 0)
2037 if (sigaction(sig, &sa, NULL) < 0)
2044 int close_pipe(int p[]) {
2050 a = close_nointr(p[0]);
2055 b = close_nointr(p[1]);
2059 return a < 0 ? a : b;
2062 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2069 while (nbytes > 0) {
2072 k = read(fd, p, nbytes);
2073 if (k < 0 && errno == EINTR)
2076 if (k < 0 && errno == EAGAIN && do_poll) {
2078 /* We knowingly ignore any return value here,
2079 * and expect that any error/EOF is reported
2082 fd_wait_for_event(fd, POLLIN, (usec_t) -1);
2087 return n > 0 ? n : (k < 0 ? -errno : 0);
2097 ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2098 const uint8_t *p = buf;
2104 while (nbytes > 0) {
2107 k = write(fd, p, nbytes);
2108 if (k < 0 && errno == EINTR)
2111 if (k < 0 && errno == EAGAIN && do_poll) {
2113 /* We knowingly ignore any return value here,
2114 * and expect that any error/EOF is reported
2117 fd_wait_for_event(fd, POLLOUT, (usec_t) -1);
2122 return n > 0 ? n : (k < 0 ? -errno : 0);
2132 int parse_size(const char *t, off_t base, off_t *size) {
2134 /* Soo, sometimes we want to parse IEC binary suffxies, and
2135 * sometimes SI decimal suffixes. This function can parse
2136 * both. Which one is the right way depends on the
2137 * context. Wikipedia suggests that SI is customary for
2138 * hardrware metrics and network speeds, while IEC is
2139 * customary for most data sizes used by software and volatile
2140 * (RAM) memory. Hence be careful which one you pick!
2142 * In either case we use just K, M, G as suffix, and not Ki,
2143 * Mi, Gi or so (as IEC would suggest). That's because that's
2144 * frickin' ugly. But this means you really need to make sure
2145 * to document which base you are parsing when you use this
2150 unsigned long long factor;
2153 static const struct table iec[] = {
2154 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2155 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2156 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2157 { "G", 1024ULL*1024ULL*1024ULL },
2158 { "M", 1024ULL*1024ULL },
2164 static const struct table si[] = {
2165 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2166 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2167 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
2168 { "G", 1000ULL*1000ULL*1000ULL },
2169 { "M", 1000ULL*1000ULL },
2175 const struct table *table;
2177 unsigned long long r = 0;
2178 unsigned n_entries, start_pos = 0;
2181 assert(base == 1000 || base == 1024);
2186 n_entries = ELEMENTSOF(si);
2189 n_entries = ELEMENTSOF(iec);
2195 unsigned long long l2;
2201 l = strtoll(p, &e, 10);
2214 if (*e >= '0' && *e <= '9') {
2217 /* strotoull itself would accept space/+/- */
2218 l2 = strtoull(e, &e2, 10);
2220 if (errno == ERANGE)
2223 /* Ignore failure. E.g. 10.M is valid */
2230 e += strspn(e, WHITESPACE);
2232 for (i = start_pos; i < n_entries; i++)
2233 if (startswith(e, table[i].suffix)) {
2234 unsigned long long tmp;
2235 if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor)
2237 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
2238 if (tmp > ULLONG_MAX - r)
2242 if ((unsigned long long) (off_t) r != r)
2245 p = e + strlen(table[i].suffix);
2261 int make_stdio(int fd) {
2266 r = dup3(fd, STDIN_FILENO, 0);
2267 s = dup3(fd, STDOUT_FILENO, 0);
2268 t = dup3(fd, STDERR_FILENO, 0);
2271 close_nointr_nofail(fd);
2273 if (r < 0 || s < 0 || t < 0)
2276 /* We rely here that the new fd has O_CLOEXEC not set */
2281 int make_null_stdio(void) {
2284 null_fd = open("/dev/null", O_RDWR|O_NOCTTY);
2288 return make_stdio(null_fd);
2291 bool is_device_path(const char *path) {
2293 /* Returns true on paths that refer to a device, either in
2294 * sysfs or in /dev */
2297 path_startswith(path, "/dev/") ||
2298 path_startswith(path, "/sys/");
2301 int dir_is_empty(const char *path) {
2302 _cleanup_closedir_ DIR *d;
2313 if (!de && errno != 0)
2319 if (!ignore_file(de->d_name))
2324 char* dirname_malloc(const char *path) {
2325 char *d, *dir, *dir2;
2342 int dev_urandom(void *p, size_t n) {
2343 _cleanup_close_ int fd;
2346 fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
2348 return errno == ENOENT ? -ENOSYS : -errno;
2350 k = loop_read(fd, p, n, true);
2353 if ((size_t) k != n)
2359 void random_bytes(void *p, size_t n) {
2360 static bool srand_called = false;
2364 r = dev_urandom(p, n);
2368 /* If some idiot made /dev/urandom unavailable to us, he'll
2369 * get a PRNG instead. */
2371 if (!srand_called) {
2374 #ifdef HAVE_SYS_AUXV_H
2375 /* The kernel provides us with a bit of entropy in
2376 * auxv, so let's try to make use of that to seed the
2377 * pseudo-random generator. It's better than
2382 auxv = (void*) getauxval(AT_RANDOM);
2384 x ^= *(unsigned*) auxv;
2387 x ^= (unsigned) now(CLOCK_REALTIME);
2388 x ^= (unsigned) gettid();
2391 srand_called = true;
2394 for (q = p; q < (uint8_t*) p + n; q ++)
2398 void rename_process(const char name[8]) {
2401 /* This is a like a poor man's setproctitle(). It changes the
2402 * comm field, argv[0], and also the glibc's internally used
2403 * name of the process. For the first one a limit of 16 chars
2404 * applies, to the second one usually one of 10 (i.e. length
2405 * of "/sbin/init"), to the third one one of 7 (i.e. length of
2406 * "systemd"). If you pass a longer string it will be
2409 prctl(PR_SET_NAME, name);
2411 if (program_invocation_name)
2412 strncpy(program_invocation_name, name, strlen(program_invocation_name));
2414 if (saved_argc > 0) {
2418 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
2420 for (i = 1; i < saved_argc; i++) {
2424 memzero(saved_argv[i], strlen(saved_argv[i]));
2429 void sigset_add_many(sigset_t *ss, ...) {
2436 while ((sig = va_arg(ap, int)) > 0)
2437 assert_se(sigaddset(ss, sig) == 0);
2441 char* gethostname_malloc(void) {
2444 assert_se(uname(&u) >= 0);
2446 if (!isempty(u.nodename) && !streq(u.nodename, "(none)"))
2447 return strdup(u.nodename);
2449 return strdup(u.sysname);
2452 bool hostname_is_set(void) {
2455 assert_se(uname(&u) >= 0);
2457 return !isempty(u.nodename) && !streq(u.nodename, "(none)");
2460 static char *lookup_uid(uid_t uid) {
2463 _cleanup_free_ char *buf = NULL;
2464 struct passwd pwbuf, *pw = NULL;
2466 /* Shortcut things to avoid NSS lookups */
2468 return strdup("root");
2470 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
2474 buf = malloc(bufsize);
2478 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
2479 return strdup(pw->pw_name);
2481 if (asprintf(&name, "%lu", (unsigned long) uid) < 0)
2487 char* getlogname_malloc(void) {
2491 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
2496 return lookup_uid(uid);
2499 char *getusername_malloc(void) {
2506 return lookup_uid(getuid());
2509 int getttyname_malloc(int fd, char **r) {
2510 char path[PATH_MAX], *c;
2515 k = ttyname_r(fd, path, sizeof(path));
2521 c = strdup(startswith(path, "/dev/") ? path + 5 : path);
2529 int getttyname_harder(int fd, char **r) {
2533 k = getttyname_malloc(fd, &s);
2537 if (streq(s, "tty")) {
2539 return get_ctty(0, NULL, r);
2546 int get_ctty_devnr(pid_t pid, dev_t *d) {
2548 _cleanup_free_ char *line = NULL;
2550 unsigned long ttynr;
2554 p = procfs_file_alloca(pid, "stat");
2555 r = read_one_line_file(p, &line);
2559 p = strrchr(line, ')');
2569 "%*d " /* session */
2574 if (major(ttynr) == 0 && minor(ttynr) == 0)
2583 int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
2584 char fn[sizeof("/dev/char/")-1 + 2*DECIMAL_STR_MAX(unsigned) + 1 + 1], *b = NULL;
2585 _cleanup_free_ char *s = NULL;
2592 k = get_ctty_devnr(pid, &devnr);
2596 snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
2598 k = readlink_malloc(fn, &s);
2604 /* This is an ugly hack */
2605 if (major(devnr) == 136) {
2606 asprintf(&b, "pts/%lu", (unsigned long) minor(devnr));
2610 /* Probably something like the ptys which have no
2611 * symlink in /dev/char. Let's return something
2612 * vaguely useful. */
2618 if (startswith(s, "/dev/"))
2620 else if (startswith(s, "../"))
2638 int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
2644 /* This returns the first error we run into, but nevertheless
2645 * tries to go on. This closes the passed fd. */
2649 close_nointr_nofail(fd);
2651 return errno == ENOENT ? 0 : -errno;
2656 bool is_dir, keep_around;
2662 if (!de && errno != 0) {
2671 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
2674 if (de->d_type == DT_UNKNOWN ||
2676 (de->d_type == DT_DIR && root_dev)) {
2677 if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
2678 if (ret == 0 && errno != ENOENT)
2683 is_dir = S_ISDIR(st.st_mode);
2686 (st.st_uid == 0 || st.st_uid == getuid()) &&
2687 (st.st_mode & S_ISVTX);
2689 is_dir = de->d_type == DT_DIR;
2690 keep_around = false;
2696 /* if root_dev is set, remove subdirectories only, if device is same as dir */
2697 if (root_dev && st.st_dev != root_dev->st_dev)
2700 subdir_fd = openat(fd, de->d_name,
2701 O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
2702 if (subdir_fd < 0) {
2703 if (ret == 0 && errno != ENOENT)
2708 r = rm_rf_children_dangerous(subdir_fd, only_dirs, honour_sticky, root_dev);
2709 if (r < 0 && ret == 0)
2713 if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
2714 if (ret == 0 && errno != ENOENT)
2718 } else if (!only_dirs && !keep_around) {
2720 if (unlinkat(fd, de->d_name, 0) < 0) {
2721 if (ret == 0 && errno != ENOENT)
2732 _pure_ static int is_temporary_fs(struct statfs *s) {
2735 return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) ||
2736 F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC);
2739 int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
2744 if (fstatfs(fd, &s) < 0) {
2745 close_nointr_nofail(fd);
2749 /* We refuse to clean disk file systems with this call. This
2750 * is extra paranoia just to be sure we never ever remove
2752 if (!is_temporary_fs(&s)) {
2753 log_error("Attempted to remove disk file system, and we can't allow that.");
2754 close_nointr_nofail(fd);
2758 return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev);
2761 static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
2767 /* We refuse to clean the root file system with this
2768 * call. This is extra paranoia to never cause a really
2769 * seriously broken system. */
2770 if (path_equal(path, "/")) {
2771 log_error("Attempted to remove entire root file system, and we can't allow that.");
2775 fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
2778 if (errno != ENOTDIR)
2782 if (statfs(path, &s) < 0)
2785 if (!is_temporary_fs(&s)) {
2786 log_error("Attempted to remove disk file system, and we can't allow that.");
2791 if (delete_root && !only_dirs)
2792 if (unlink(path) < 0 && errno != ENOENT)
2799 if (fstatfs(fd, &s) < 0) {
2800 close_nointr_nofail(fd);
2804 if (!is_temporary_fs(&s)) {
2805 log_error("Attempted to remove disk file system, and we can't allow that.");
2806 close_nointr_nofail(fd);
2811 r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL);
2814 if (honour_sticky && file_is_priv_sticky(path) > 0)
2817 if (rmdir(path) < 0 && errno != ENOENT) {
2826 int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
2827 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false);
2830 int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
2831 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, true);
2834 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
2837 /* Under the assumption that we are running privileged we
2838 * first change the access mode and only then hand out
2839 * ownership to avoid a window where access is too open. */
2841 if (mode != (mode_t) -1)
2842 if (chmod(path, mode) < 0)
2845 if (uid != (uid_t) -1 || gid != (gid_t) -1)
2846 if (chown(path, uid, gid) < 0)
2852 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
2855 /* Under the assumption that we are running privileged we
2856 * first change the access mode and only then hand out
2857 * ownership to avoid a window where access is too open. */
2859 if (mode != (mode_t) -1)
2860 if (fchmod(fd, mode) < 0)
2863 if (uid != (uid_t) -1 || gid != (gid_t) -1)
2864 if (fchown(fd, uid, gid) < 0)
2870 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
2874 /* Allocates the cpuset in the right size */
2877 if (!(r = CPU_ALLOC(n)))
2880 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
2881 CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
2891 if (errno != EINVAL)
2898 int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) {
2899 static const char status_indent[] = " "; /* "[" STATUS "] " */
2900 _cleanup_free_ char *s = NULL;
2901 _cleanup_close_ int fd = -1;
2902 struct iovec iovec[6] = {};
2904 static bool prev_ephemeral;
2908 /* This is independent of logging, as status messages are
2909 * optional and go exclusively to the console. */
2911 if (vasprintf(&s, format, ap) < 0)
2914 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
2927 sl = status ? sizeof(status_indent)-1 : 0;
2933 e = ellipsize(s, emax, 75);
2941 IOVEC_SET_STRING(iovec[n++], "\r" ANSI_ERASE_TO_END_OF_LINE);
2942 prev_ephemeral = ephemeral;
2945 if (!isempty(status)) {
2946 IOVEC_SET_STRING(iovec[n++], "[");
2947 IOVEC_SET_STRING(iovec[n++], status);
2948 IOVEC_SET_STRING(iovec[n++], "] ");
2950 IOVEC_SET_STRING(iovec[n++], status_indent);
2953 IOVEC_SET_STRING(iovec[n++], s);
2955 IOVEC_SET_STRING(iovec[n++], "\n");
2957 if (writev(fd, iovec, n) < 0)
2963 int status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...) {
2969 va_start(ap, format);
2970 r = status_vprintf(status, ellipse, ephemeral, format, ap);
2976 char *replace_env(const char *format, char **env) {
2983 const char *e, *word = format;
2988 for (e = format; *e; e ++) {
2999 if (!(k = strnappend(r, word, e-word-1)))
3008 } else if (*e == '$') {
3009 if (!(k = strnappend(r, word, e-word)))
3025 t = strempty(strv_env_get_n(env, word+2, e-word-2));
3027 k = strappend(r, t);
3041 if (!(k = strnappend(r, word, e-word)))
3052 char **replace_env_argv(char **argv, char **env) {
3054 unsigned k = 0, l = 0;
3056 l = strv_length(argv);
3058 if (!(r = new(char*, l+1)))
3061 STRV_FOREACH(i, argv) {
3063 /* If $FOO appears as single word, replace it by the split up variable */
3064 if ((*i)[0] == '$' && (*i)[1] != '{') {
3069 e = strv_env_get(env, *i+1);
3072 if (!(m = strv_split_quoted(e))) {
3083 if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
3092 memcpy(r + k, m, q * sizeof(char*));
3100 /* If ${FOO} appears as part of a word, replace it by the variable as-is */
3101 if (!(r[k++] = replace_env(*i, env))) {
3111 int fd_columns(int fd) {
3112 struct winsize ws = {};
3114 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3123 unsigned columns(void) {
3127 if (_likely_(cached_columns > 0))
3128 return cached_columns;
3131 e = getenv("COLUMNS");
3136 c = fd_columns(STDOUT_FILENO);
3145 int fd_lines(int fd) {
3146 struct winsize ws = {};
3148 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3157 unsigned lines(void) {
3161 if (_likely_(cached_lines > 0))
3162 return cached_lines;
3165 e = getenv("LINES");
3170 l = fd_lines(STDOUT_FILENO);
3176 return cached_lines;
3179 /* intended to be used as a SIGWINCH sighandler */
3180 void columns_lines_cache_reset(int signum) {
3186 static int cached_on_tty = -1;
3188 if (_unlikely_(cached_on_tty < 0))
3189 cached_on_tty = isatty(STDOUT_FILENO) > 0;
3191 return cached_on_tty;
3194 int files_same(const char *filea, const char *fileb) {
3197 if (stat(filea, &a) < 0)
3200 if (stat(fileb, &b) < 0)
3203 return a.st_dev == b.st_dev &&
3204 a.st_ino == b.st_ino;
3207 int running_in_chroot(void) {
3210 ret = files_same("/proc/1/root", "/");
3217 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
3222 assert(percent <= 100);
3223 assert(new_length >= 3);
3225 if (old_length <= 3 || old_length <= new_length)
3226 return strndup(s, old_length);
3228 r = new0(char, new_length+1);
3232 x = (new_length * percent) / 100;
3234 if (x > new_length - 3)
3242 s + old_length - (new_length - x - 3),
3243 new_length - x - 3);
3248 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
3252 unsigned k, len, len2;
3255 assert(percent <= 100);
3256 assert(new_length >= 3);
3258 /* if no multibyte characters use ascii_ellipsize_mem for speed */
3259 if (ascii_is_valid(s))
3260 return ascii_ellipsize_mem(s, old_length, new_length, percent);
3262 if (old_length <= 3 || old_length <= new_length)
3263 return strndup(s, old_length);
3265 x = (new_length * percent) / 100;
3267 if (x > new_length - 3)
3271 for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
3274 c = utf8_encoded_to_unichar(i);
3277 k += unichar_iswide(c) ? 2 : 1;
3280 if (k > x) /* last character was wide and went over quota */
3283 for (j = s + old_length; k < new_length && j > i; ) {
3286 j = utf8_prev_char(j);
3287 c = utf8_encoded_to_unichar(j);
3290 k += unichar_iswide(c) ? 2 : 1;
3294 /* we don't actually need to ellipsize */
3296 return memdup(s, old_length + 1);
3298 /* make space for ellipsis */
3299 j = utf8_next_char(j);
3302 len2 = s + old_length - j;
3303 e = new(char, len + 3 + len2 + 1);
3308 printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
3309 old_length, new_length, x, len, len2, k);
3313 e[len] = 0xe2; /* tri-dot ellipsis: … */
3317 memcpy(e + len + 3, j, len2 + 1);
3322 char *ellipsize(const char *s, size_t length, unsigned percent) {
3323 return ellipsize_mem(s, strlen(s), length, percent);
3326 int touch(const char *path) {
3331 /* This just opens the file for writing, ensuring it
3332 * exists. It doesn't call utimensat() the way /usr/bin/touch
3335 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644);
3339 close_nointr_nofail(fd);
3343 char *unquote(const char *s, const char* quotes) {
3347 /* This is rather stupid, simply removes the heading and
3348 * trailing quotes if there is one. Doesn't care about
3349 * escaping or anything. We should make this smarter one
3356 if (strchr(quotes, s[0]) && s[l-1] == s[0])
3357 return strndup(s+1, l-2);
3362 char *normalize_env_assignment(const char *s) {
3363 _cleanup_free_ char *name = NULL, *value = NULL, *p = NULL;
3366 eq = strchr(s, '=');
3378 memmove(r, t, strlen(t) + 1);
3382 name = strndup(s, eq - s);
3390 value = unquote(strstrip(p), QUOTES);
3394 if (asprintf(&r, "%s=%s", strstrip(name), value) < 0)
3400 int wait_for_terminate(pid_t pid, siginfo_t *status) {
3411 if (waitid(P_PID, pid, status, WEXITED) < 0) {
3423 int wait_for_terminate_and_warn(const char *name, pid_t pid) {
3430 r = wait_for_terminate(pid, &status);
3432 log_warning("Failed to wait for %s: %s", name, strerror(-r));
3436 if (status.si_code == CLD_EXITED) {
3437 if (status.si_status != 0) {
3438 log_warning("%s failed with error code %i.", name, status.si_status);
3439 return status.si_status;
3442 log_debug("%s succeeded.", name);
3445 } else if (status.si_code == CLD_KILLED ||
3446 status.si_code == CLD_DUMPED) {
3448 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
3452 log_warning("%s failed due to unknown reason.", name);
3456 noreturn void freeze(void) {
3458 /* Make sure nobody waits for us on a socket anymore */
3459 close_all_fds(NULL, 0);
3467 bool null_or_empty(struct stat *st) {
3470 if (S_ISREG(st->st_mode) && st->st_size <= 0)
3473 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
3479 int null_or_empty_path(const char *fn) {
3484 if (stat(fn, &st) < 0)
3487 return null_or_empty(&st);
3490 DIR *xopendirat(int fd, const char *name, int flags) {
3494 assert(!(flags & O_CREAT));
3496 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
3502 close_nointr_nofail(nfd);
3509 int signal_from_string_try_harder(const char *s) {
3513 signo = signal_from_string(s);
3515 if (startswith(s, "SIG"))
3516 return signal_from_string(s+3);
3521 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
3522 _cleanup_free_ char *t = NULL, *u = NULL;
3525 u = unquote(tagvalue, "\"\'");
3529 enc_len = strlen(u) * 4 + 1;
3530 t = new(char, enc_len);
3534 if (encode_devnode_name(u, t, enc_len) < 0)
3537 return strjoin("/dev/disk/by-", by, "/", t, NULL);
3540 char *fstab_node_to_udev_node(const char *p) {
3543 if (startswith(p, "LABEL="))
3544 return tag_to_udev_node(p+6, "label");
3546 if (startswith(p, "UUID="))
3547 return tag_to_udev_node(p+5, "uuid");
3549 if (startswith(p, "PARTUUID="))
3550 return tag_to_udev_node(p+9, "partuuid");
3552 if (startswith(p, "PARTLABEL="))
3553 return tag_to_udev_node(p+10, "partlabel");
3558 bool tty_is_vc(const char *tty) {
3561 if (startswith(tty, "/dev/"))
3564 return vtnr_from_tty(tty) >= 0;
3567 bool tty_is_console(const char *tty) {
3570 if (startswith(tty, "/dev/"))
3573 return streq(tty, "console");
3576 int vtnr_from_tty(const char *tty) {
3581 if (startswith(tty, "/dev/"))
3584 if (!startswith(tty, "tty") )
3587 if (tty[3] < '0' || tty[3] > '9')
3590 r = safe_atoi(tty+3, &i);
3594 if (i < 0 || i > 63)
3600 char *resolve_dev_console(char **active) {
3603 /* Resolve where /dev/console is pointing to, if /sys is actually ours
3604 * (i.e. not read-only-mounted which is a sign for container setups) */
3606 if (path_is_read_only_fs("/sys") > 0)
3609 if (read_one_line_file("/sys/class/tty/console/active", active) < 0)
3612 /* If multiple log outputs are configured the last one is what
3613 * /dev/console points to */
3614 tty = strrchr(*active, ' ');
3620 if (streq(tty, "tty0")) {
3623 /* Get the active VC (e.g. tty1) */
3624 if (read_one_line_file("/sys/class/tty/tty0/active", &tmp) >= 0) {
3626 tty = *active = tmp;
3633 bool tty_is_vc_resolve(const char *tty) {
3634 _cleanup_free_ char *active = NULL;
3638 if (startswith(tty, "/dev/"))
3641 if (streq(tty, "console")) {
3642 tty = resolve_dev_console(&active);
3647 return tty_is_vc(tty);
3650 const char *default_term_for_tty(const char *tty) {
3653 return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102";
3656 bool dirent_is_file(const struct dirent *de) {
3659 if (ignore_file(de->d_name))
3662 if (de->d_type != DT_REG &&
3663 de->d_type != DT_LNK &&
3664 de->d_type != DT_UNKNOWN)
3670 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
3673 if (de->d_type != DT_REG &&
3674 de->d_type != DT_LNK &&
3675 de->d_type != DT_UNKNOWN)
3678 if (ignore_file_allow_backup(de->d_name))
3681 return endswith(de->d_name, suffix);
3684 void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv[]) {
3690 /* Executes all binaries in a directory in parallel and waits
3691 * for them to finish. Optionally a timeout is applied. */
3693 executor_pid = fork();
3694 if (executor_pid < 0) {
3695 log_error("Failed to fork: %m");
3698 } else if (executor_pid == 0) {
3699 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
3700 _cleanup_closedir_ DIR *_d = NULL;
3704 /* We fork this all off from a child process so that
3705 * we can somewhat cleanly make use of SIGALRM to set
3708 reset_all_signal_handlers();
3710 assert_se(sigemptyset(&ss) == 0);
3711 assert_se(sigprocmask(SIG_SETMASK, &ss, NULL) == 0);
3713 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
3716 d = _d = opendir(directory);
3718 if (errno == ENOENT)
3719 _exit(EXIT_SUCCESS);
3721 log_error("Failed to enumerate directory %s: %m", directory);
3722 _exit(EXIT_FAILURE);
3726 pids = hashmap_new(NULL, NULL);
3729 _exit(EXIT_FAILURE);
3732 FOREACH_DIRENT(de, d, break) {
3733 _cleanup_free_ char *path = NULL;
3736 if (!dirent_is_file(de))
3739 if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
3741 _exit(EXIT_FAILURE);
3746 log_error("Failed to fork: %m");
3748 } else if (pid == 0) {
3751 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
3761 log_error("Failed to execute %s: %m", path);
3762 _exit(EXIT_FAILURE);
3766 log_debug("Spawned %s as " PID_FMT ".", path, pid);
3768 r = hashmap_put(pids, UINT_TO_PTR(pid), path);
3771 _exit(EXIT_FAILURE);
3777 /* Abort execution of this process after the
3778 * timout. We simply rely on SIGALRM as default action
3779 * terminating the process, and turn on alarm(). */
3781 if (timeout != (usec_t) -1)
3782 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
3784 while (!hashmap_isempty(pids)) {
3785 _cleanup_free_ char *path = NULL;
3788 pid = PTR_TO_UINT(hashmap_first_key(pids));
3791 path = hashmap_remove(pids, UINT_TO_PTR(pid));
3794 wait_for_terminate_and_warn(path, pid);
3797 _exit(EXIT_SUCCESS);
3800 wait_for_terminate_and_warn(directory, executor_pid);
3803 int kill_and_sigcont(pid_t pid, int sig) {
3806 r = kill(pid, sig) < 0 ? -errno : 0;
3814 bool nulstr_contains(const char*nulstr, const char *needle) {
3820 NULSTR_FOREACH(i, nulstr)
3821 if (streq(i, needle))
3827 bool plymouth_running(void) {
3828 return access("/run/plymouth/pid", F_OK) >= 0;
3831 char* strshorten(char *s, size_t l) {
3840 static bool hostname_valid_char(char c) {
3842 (c >= 'a' && c <= 'z') ||
3843 (c >= 'A' && c <= 'Z') ||
3844 (c >= '0' && c <= '9') ||
3850 bool hostname_is_valid(const char *s) {
3857 for (p = s, dot = true; *p; p++) {
3864 if (!hostname_valid_char(*p))
3874 if (p-s > HOST_NAME_MAX)
3880 char* hostname_cleanup(char *s, bool lowercase) {
3884 for (p = s, d = s, dot = true; *p; p++) {
3891 } else if (hostname_valid_char(*p)) {
3892 *(d++) = lowercase ? tolower(*p) : *p;
3903 strshorten(s, HOST_NAME_MAX);
3908 int pipe_eof(int fd) {
3909 struct pollfd pollfd = {
3911 .events = POLLIN|POLLHUP,
3916 r = poll(&pollfd, 1, 0);
3923 return pollfd.revents & POLLHUP;
3926 int fd_wait_for_event(int fd, int event, usec_t t) {
3928 struct pollfd pollfd = {
3936 r = ppoll(&pollfd, 1, t == (usec_t) -1 ? NULL : timespec_store(&ts, t), NULL);
3943 return pollfd.revents;
3946 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
3957 t = new(char, strlen(path) + 1 + 6 + 1);
3961 fn = basename(path);
3965 stpcpy(stpcpy(t+k+1, fn), "XXXXXX");
3967 fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
3973 f = fdopen(fd, "we");
3986 int terminal_vhangup_fd(int fd) {
3989 if (ioctl(fd, TIOCVHANGUP) < 0)
3995 int terminal_vhangup(const char *name) {
3998 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4002 r = terminal_vhangup_fd(fd);
4003 close_nointr_nofail(fd);
4008 int vt_disallocate(const char *name) {
4012 /* Deallocate the VT if possible. If not possible
4013 * (i.e. because it is the active one), at least clear it
4014 * entirely (including the scrollback buffer) */
4016 if (!startswith(name, "/dev/"))
4019 if (!tty_is_vc(name)) {
4020 /* So this is not a VT. I guess we cannot deallocate
4021 * it then. But let's at least clear the screen */
4023 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4028 "\033[r" /* clear scrolling region */
4029 "\033[H" /* move home */
4030 "\033[2J", /* clear screen */
4032 close_nointr_nofail(fd);
4037 if (!startswith(name, "/dev/tty"))
4040 r = safe_atou(name+8, &u);
4047 /* Try to deallocate */
4048 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
4052 r = ioctl(fd, VT_DISALLOCATE, u);
4053 close_nointr_nofail(fd);
4061 /* Couldn't deallocate, so let's clear it fully with
4063 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4068 "\033[r" /* clear scrolling region */
4069 "\033[H" /* move home */
4070 "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
4072 close_nointr_nofail(fd);
4077 int copy_file(const char *from, const char *to, int flags) {
4078 _cleanup_close_ int fdf = -1;
4084 fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
4088 fdt = open(to, flags|O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644);
4096 n = read(fdf, buf, sizeof(buf));
4110 k = loop_write(fdt, buf, n, false);
4112 r = k < 0 ? k : (errno ? -errno : -EIO);
4121 r = close_nointr(fdt);
4131 int symlink_atomic(const char *from, const char *to) {
4133 _cleanup_free_ char *t;
4143 t = new(char, strlen(to) + 1 + 16 + 1);
4151 x = stpcpy(t+k+1, fn);
4154 for (i = 0; i < 16; i++) {
4155 *(x++) = hexchar(u & 0xF);
4161 if (symlink(from, t) < 0)
4164 if (rename(t, to) < 0) {
4173 bool display_is_local(const char *display) {
4177 display[0] == ':' &&
4178 display[1] >= '0' &&
4182 int socket_from_display(const char *display, char **path) {
4189 if (!display_is_local(display))
4192 k = strspn(display+1, "0123456789");
4194 f = new(char, sizeof("/tmp/.X11-unix/X") + k);
4198 c = stpcpy(f, "/tmp/.X11-unix/X");
4199 memcpy(c, display+1, k);
4208 const char **username,
4209 uid_t *uid, gid_t *gid,
4211 const char **shell) {
4219 /* We enforce some special rules for uid=0: in order to avoid
4220 * NSS lookups for root we hardcode its data. */
4222 if (streq(*username, "root") || streq(*username, "0")) {
4240 if (parse_uid(*username, &u) >= 0) {
4244 /* If there are multiple users with the same id, make
4245 * sure to leave $USER to the configured value instead
4246 * of the first occurrence in the database. However if
4247 * the uid was configured by a numeric uid, then let's
4248 * pick the real username from /etc/passwd. */
4250 *username = p->pw_name;
4253 p = getpwnam(*username);
4257 return errno > 0 ? -errno : -ESRCH;
4269 *shell = p->pw_shell;
4274 char* uid_to_name(uid_t uid) {
4279 return strdup("root");
4283 return strdup(p->pw_name);
4285 if (asprintf(&r, "%lu", (unsigned long) uid) < 0)
4291 char* gid_to_name(gid_t gid) {
4296 return strdup("root");
4300 return strdup(p->gr_name);
4302 if (asprintf(&r, "%lu", (unsigned long) gid) < 0)
4308 int get_group_creds(const char **groupname, gid_t *gid) {
4314 /* We enforce some special rules for gid=0: in order to avoid
4315 * NSS lookups for root we hardcode its data. */
4317 if (streq(*groupname, "root") || streq(*groupname, "0")) {
4318 *groupname = "root";
4326 if (parse_gid(*groupname, &id) >= 0) {
4331 *groupname = g->gr_name;
4334 g = getgrnam(*groupname);
4338 return errno > 0 ? -errno : -ESRCH;
4346 int in_gid(gid_t gid) {
4348 int ngroups_max, r, i;
4350 if (getgid() == gid)
4353 if (getegid() == gid)
4356 ngroups_max = sysconf(_SC_NGROUPS_MAX);
4357 assert(ngroups_max > 0);
4359 gids = alloca(sizeof(gid_t) * ngroups_max);
4361 r = getgroups(ngroups_max, gids);
4365 for (i = 0; i < r; i++)
4372 int in_group(const char *name) {
4376 r = get_group_creds(&name, &gid);
4383 int glob_exists(const char *path) {
4384 _cleanup_globfree_ glob_t g = {};
4390 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
4392 if (k == GLOB_NOMATCH)
4394 else if (k == GLOB_NOSPACE)
4397 return !strv_isempty(g.gl_pathv);
4399 return errno ? -errno : -EIO;
4402 int glob_extend(char ***strv, const char *path) {
4403 _cleanup_globfree_ glob_t g = {};
4408 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
4410 if (k == GLOB_NOMATCH)
4412 else if (k == GLOB_NOSPACE)
4414 else if (k != 0 || strv_isempty(g.gl_pathv))
4415 return errno ? -errno : -EIO;
4417 STRV_FOREACH(p, g.gl_pathv) {
4418 k = strv_extend(strv, *p);
4426 int dirent_ensure_type(DIR *d, struct dirent *de) {
4432 if (de->d_type != DT_UNKNOWN)
4435 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
4439 S_ISREG(st.st_mode) ? DT_REG :
4440 S_ISDIR(st.st_mode) ? DT_DIR :
4441 S_ISLNK(st.st_mode) ? DT_LNK :
4442 S_ISFIFO(st.st_mode) ? DT_FIFO :
4443 S_ISSOCK(st.st_mode) ? DT_SOCK :
4444 S_ISCHR(st.st_mode) ? DT_CHR :
4445 S_ISBLK(st.st_mode) ? DT_BLK :
4451 int in_search_path(const char *path, char **search) {
4453 _cleanup_free_ char *parent = NULL;
4456 r = path_get_parent(path, &parent);
4460 STRV_FOREACH(i, search)
4461 if (path_equal(parent, *i))
4467 int get_files_in_directory(const char *path, char ***list) {
4468 _cleanup_closedir_ DIR *d = NULL;
4469 size_t bufsize = 0, n = 0;
4470 _cleanup_strv_free_ char **l = NULL;
4474 /* Returns all files in a directory in *list, and the number
4475 * of files as return value. If list is NULL returns only the
4487 if (!de && errno != 0)
4492 dirent_ensure_type(d, de);
4494 if (!dirent_is_file(de))
4498 /* one extra slot is needed for the terminating NULL */
4499 if (!GREEDY_REALLOC(l, bufsize, n + 2))
4502 l[n] = strdup(de->d_name);
4513 l = NULL; /* avoid freeing */
4519 char *strjoin(const char *x, ...) {
4533 t = va_arg(ap, const char *);
4538 if (n > ((size_t) -1) - l) {
4562 t = va_arg(ap, const char *);
4576 bool is_main_thread(void) {
4577 static thread_local int cached = 0;
4579 if (_unlikely_(cached == 0))
4580 cached = getpid() == gettid() ? 1 : -1;
4585 int block_get_whole_disk(dev_t d, dev_t *ret) {
4592 /* If it has a queue this is good enough for us */
4593 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
4596 r = access(p, F_OK);
4604 /* If it is a partition find the originating device */
4605 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
4608 r = access(p, F_OK);
4614 /* Get parent dev_t */
4615 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
4618 r = read_one_line_file(p, &s);
4624 r = sscanf(s, "%u:%u", &m, &n);
4630 /* Only return this if it is really good enough for us. */
4631 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
4634 r = access(p, F_OK);
4638 *ret = makedev(m, n);
4645 int file_is_priv_sticky(const char *p) {
4650 if (lstat(p, &st) < 0)
4654 (st.st_uid == 0 || st.st_uid == getuid()) &&
4655 (st.st_mode & S_ISVTX);
4658 static const char *const ioprio_class_table[] = {
4659 [IOPRIO_CLASS_NONE] = "none",
4660 [IOPRIO_CLASS_RT] = "realtime",
4661 [IOPRIO_CLASS_BE] = "best-effort",
4662 [IOPRIO_CLASS_IDLE] = "idle"
4665 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
4667 static const char *const sigchld_code_table[] = {
4668 [CLD_EXITED] = "exited",
4669 [CLD_KILLED] = "killed",
4670 [CLD_DUMPED] = "dumped",
4671 [CLD_TRAPPED] = "trapped",
4672 [CLD_STOPPED] = "stopped",
4673 [CLD_CONTINUED] = "continued",
4676 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
4678 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
4679 [LOG_FAC(LOG_KERN)] = "kern",
4680 [LOG_FAC(LOG_USER)] = "user",
4681 [LOG_FAC(LOG_MAIL)] = "mail",
4682 [LOG_FAC(LOG_DAEMON)] = "daemon",
4683 [LOG_FAC(LOG_AUTH)] = "auth",
4684 [LOG_FAC(LOG_SYSLOG)] = "syslog",
4685 [LOG_FAC(LOG_LPR)] = "lpr",
4686 [LOG_FAC(LOG_NEWS)] = "news",
4687 [LOG_FAC(LOG_UUCP)] = "uucp",
4688 [LOG_FAC(LOG_CRON)] = "cron",
4689 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
4690 [LOG_FAC(LOG_FTP)] = "ftp",
4691 [LOG_FAC(LOG_LOCAL0)] = "local0",
4692 [LOG_FAC(LOG_LOCAL1)] = "local1",
4693 [LOG_FAC(LOG_LOCAL2)] = "local2",
4694 [LOG_FAC(LOG_LOCAL3)] = "local3",
4695 [LOG_FAC(LOG_LOCAL4)] = "local4",
4696 [LOG_FAC(LOG_LOCAL5)] = "local5",
4697 [LOG_FAC(LOG_LOCAL6)] = "local6",
4698 [LOG_FAC(LOG_LOCAL7)] = "local7"
4701 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
4703 static const char *const log_level_table[] = {
4704 [LOG_EMERG] = "emerg",
4705 [LOG_ALERT] = "alert",
4706 [LOG_CRIT] = "crit",
4708 [LOG_WARNING] = "warning",
4709 [LOG_NOTICE] = "notice",
4710 [LOG_INFO] = "info",
4711 [LOG_DEBUG] = "debug"
4714 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
4716 static const char* const sched_policy_table[] = {
4717 [SCHED_OTHER] = "other",
4718 [SCHED_BATCH] = "batch",
4719 [SCHED_IDLE] = "idle",
4720 [SCHED_FIFO] = "fifo",
4724 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
4726 static const char* const rlimit_table[_RLIMIT_MAX] = {
4727 [RLIMIT_CPU] = "LimitCPU",
4728 [RLIMIT_FSIZE] = "LimitFSIZE",
4729 [RLIMIT_DATA] = "LimitDATA",
4730 [RLIMIT_STACK] = "LimitSTACK",
4731 [RLIMIT_CORE] = "LimitCORE",
4732 [RLIMIT_RSS] = "LimitRSS",
4733 [RLIMIT_NOFILE] = "LimitNOFILE",
4734 [RLIMIT_AS] = "LimitAS",
4735 [RLIMIT_NPROC] = "LimitNPROC",
4736 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
4737 [RLIMIT_LOCKS] = "LimitLOCKS",
4738 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
4739 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
4740 [RLIMIT_NICE] = "LimitNICE",
4741 [RLIMIT_RTPRIO] = "LimitRTPRIO",
4742 [RLIMIT_RTTIME] = "LimitRTTIME"
4745 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
4747 static const char* const ip_tos_table[] = {
4748 [IPTOS_LOWDELAY] = "low-delay",
4749 [IPTOS_THROUGHPUT] = "throughput",
4750 [IPTOS_RELIABILITY] = "reliability",
4751 [IPTOS_LOWCOST] = "low-cost",
4754 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
4756 static const char *const __signal_table[] = {
4773 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
4784 [SIGVTALRM] = "VTALRM",
4786 [SIGWINCH] = "WINCH",
4792 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
4794 const char *signal_to_string(int signo) {
4795 static thread_local char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1];
4798 name = __signal_to_string(signo);
4802 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
4803 snprintf(buf, sizeof(buf), "RTMIN+%d", signo - SIGRTMIN);
4805 snprintf(buf, sizeof(buf), "%d", signo);
4810 int signal_from_string(const char *s) {
4815 signo = __signal_from_string(s);
4819 if (startswith(s, "RTMIN+")) {
4823 if (safe_atou(s, &u) >= 0) {
4824 signo = (int) u + offset;
4825 if (signo > 0 && signo < _NSIG)
4831 bool kexec_loaded(void) {
4832 bool loaded = false;
4835 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
4843 int strdup_or_null(const char *a, char **b) {
4861 int prot_from_flags(int flags) {
4863 switch (flags & O_ACCMODE) {
4872 return PROT_READ|PROT_WRITE;
4879 char *format_bytes(char *buf, size_t l, off_t t) {
4882 static const struct {
4886 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
4887 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
4888 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
4889 { "G", 1024ULL*1024ULL*1024ULL },
4890 { "M", 1024ULL*1024ULL },
4894 for (i = 0; i < ELEMENTSOF(table); i++) {
4896 if (t >= table[i].factor) {
4899 (unsigned long long) (t / table[i].factor),
4900 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
4907 snprintf(buf, l, "%lluB", (unsigned long long) t);
4915 void* memdup(const void *p, size_t l) {
4928 int fd_inc_sndbuf(int fd, size_t n) {
4930 socklen_t l = sizeof(value);
4932 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
4933 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
4936 /* If we have the privileges we will ignore the kernel limit. */
4939 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
4940 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
4946 int fd_inc_rcvbuf(int fd, size_t n) {
4948 socklen_t l = sizeof(value);
4950 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
4951 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
4954 /* If we have the privileges we will ignore the kernel limit. */
4957 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
4958 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
4963 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
4964 pid_t parent_pid, agent_pid;
4966 bool stdout_is_tty, stderr_is_tty;
4974 parent_pid = getpid();
4976 /* Spawns a temporary TTY agent, making sure it goes away when
4983 if (agent_pid != 0) {
4990 * Make sure the agent goes away when the parent dies */
4991 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
4992 _exit(EXIT_FAILURE);
4994 /* Check whether our parent died before we were able
4995 * to set the death signal */
4996 if (getppid() != parent_pid)
4997 _exit(EXIT_SUCCESS);
4999 /* Don't leak fds to the agent */
5000 close_all_fds(except, n_except);
5002 stdout_is_tty = isatty(STDOUT_FILENO);
5003 stderr_is_tty = isatty(STDERR_FILENO);
5005 if (!stdout_is_tty || !stderr_is_tty) {
5006 /* Detach from stdout/stderr. and reopen
5007 * /dev/tty for them. This is important to
5008 * ensure that when systemctl is started via
5009 * popen() or a similar call that expects to
5010 * read EOF we actually do generate EOF and
5011 * not delay this indefinitely by because we
5012 * keep an unused copy of stdin around. */
5013 fd = open("/dev/tty", O_WRONLY);
5015 log_error("Failed to open /dev/tty: %m");
5016 _exit(EXIT_FAILURE);
5020 dup2(fd, STDOUT_FILENO);
5023 dup2(fd, STDERR_FILENO);
5029 /* Count arguments */
5031 for (n = 0; va_arg(ap, char*); n++)
5036 l = alloca(sizeof(char *) * (n + 1));
5038 /* Fill in arguments */
5040 for (i = 0; i <= n; i++)
5041 l[i] = va_arg(ap, char*);
5045 _exit(EXIT_FAILURE);
5048 int setrlimit_closest(int resource, const struct rlimit *rlim) {
5049 struct rlimit highest, fixed;
5053 if (setrlimit(resource, rlim) >= 0)
5059 /* So we failed to set the desired setrlimit, then let's try
5060 * to get as close as we can */
5061 assert_se(getrlimit(resource, &highest) == 0);
5063 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
5064 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
5066 if (setrlimit(resource, &fixed) < 0)
5072 int getenv_for_pid(pid_t pid, const char *field, char **_value) {
5073 _cleanup_fclose_ FILE *f = NULL;
5084 path = procfs_file_alloca(pid, "environ");
5086 f = fopen(path, "re");
5094 char line[LINE_MAX];
5097 for (i = 0; i < sizeof(line)-1; i++) {
5101 if (_unlikely_(c == EOF)) {
5111 if (memcmp(line, field, l) == 0 && line[l] == '=') {
5112 value = strdup(line + l + 1);
5126 bool is_valid_documentation_url(const char *url) {
5129 if (startswith(url, "http://") && url[7])
5132 if (startswith(url, "https://") && url[8])
5135 if (startswith(url, "file:") && url[5])
5138 if (startswith(url, "info:") && url[5])
5141 if (startswith(url, "man:") && url[4])
5147 bool in_initrd(void) {
5148 static int saved = -1;
5154 /* We make two checks here:
5156 * 1. the flag file /etc/initrd-release must exist
5157 * 2. the root file system must be a memory file system
5159 * The second check is extra paranoia, since misdetecting an
5160 * initrd can have bad bad consequences due the initrd
5161 * emptying when transititioning to the main systemd.
5164 saved = access("/etc/initrd-release", F_OK) >= 0 &&
5165 statfs("/", &s) >= 0 &&
5166 is_temporary_fs(&s);
5171 void warn_melody(void) {
5172 _cleanup_close_ int fd = -1;
5174 fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
5178 /* Yeah, this is synchronous. Kinda sucks. But well... */
5180 ioctl(fd, KIOCSOUND, (int)(1193180/440));
5181 usleep(125*USEC_PER_MSEC);
5183 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5184 usleep(125*USEC_PER_MSEC);
5186 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5187 usleep(125*USEC_PER_MSEC);
5189 ioctl(fd, KIOCSOUND, 0);
5192 int make_console_stdio(void) {
5195 /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
5197 fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1);
5199 log_error("Failed to acquire terminal: %s", strerror(-fd));
5205 log_error("Failed to duplicate terminal fd: %s", strerror(-r));
5212 int get_home_dir(char **_h) {
5220 /* Take the user specified one */
5231 /* Hardcode home directory for root to avoid NSS */
5234 h = strdup("/root");
5242 /* Check the database... */
5246 return errno > 0 ? -errno : -ESRCH;
5248 if (!path_is_absolute(p->pw_dir))
5251 h = strdup(p->pw_dir);
5259 int get_shell(char **_s) {
5267 /* Take the user specified one */
5268 e = getenv("SHELL");
5278 /* Hardcode home directory for root to avoid NSS */
5281 s = strdup("/bin/sh");
5289 /* Check the database... */
5293 return errno > 0 ? -errno : -ESRCH;
5295 if (!path_is_absolute(p->pw_shell))
5298 s = strdup(p->pw_shell);
5306 bool filename_is_safe(const char *p) {
5320 if (strlen(p) > FILENAME_MAX)
5326 bool string_is_safe(const char *p) {
5331 for (t = p; *t; t++) {
5332 if (*t > 0 && *t < ' ')
5335 if (strchr("\\\"\'", *t))
5343 * Check if a string contains control characters.
5344 * Spaces and tabs are not considered control characters.
5346 bool string_has_cc(const char *p) {
5351 for (t = p; *t; t++)
5352 if (*t > 0 && *t < ' ' && *t != '\t')
5358 bool path_is_safe(const char *p) {
5363 if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
5366 if (strlen(p) > PATH_MAX)
5369 /* The following two checks are not really dangerous, but hey, they still are confusing */
5370 if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
5373 if (strstr(p, "//"))
5379 /* hey glibc, APIs with callbacks without a user pointer are so useless */
5380 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
5381 int (*compar) (const void *, const void *, void *), void *arg) {
5390 p = (void *)(((const char *) base) + (idx * size));
5391 comparison = compar(key, p, arg);
5394 else if (comparison > 0)
5402 bool is_locale_utf8(void) {
5404 static int cached_answer = -1;
5406 if (cached_answer >= 0)
5409 if (!setlocale(LC_ALL, "")) {
5410 cached_answer = true;
5414 set = nl_langinfo(CODESET);
5416 cached_answer = true;
5420 if (streq(set, "UTF-8")) {
5421 cached_answer = true;
5425 /* For LC_CTYPE=="C" return true, because CTYPE is effectly
5426 * unset and everything can do to UTF-8 nowadays. */
5427 set = setlocale(LC_CTYPE, NULL);
5429 cached_answer = true;
5433 /* Check result, but ignore the result if C was set
5437 !getenv("LC_ALL") &&
5438 !getenv("LC_CTYPE") &&
5442 return (bool) cached_answer;
5445 const char *draw_special_char(DrawSpecialChar ch) {
5446 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
5448 [DRAW_TREE_VERT] = "\342\224\202 ", /* │ */
5449 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
5450 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
5451 [DRAW_TREE_SPACE] = " ", /* */
5452 [DRAW_TRIANGULAR_BULLET] = "\342\200\243 ", /* ‣ */
5453 [DRAW_BLACK_CIRCLE] = "\342\227\217 ", /* ● */
5455 /* ASCII fallback */ {
5456 [DRAW_TREE_VERT] = "| ",
5457 [DRAW_TREE_BRANCH] = "|-",
5458 [DRAW_TREE_RIGHT] = "`-",
5459 [DRAW_TREE_SPACE] = " ",
5460 [DRAW_TRIANGULAR_BULLET] = "> ",
5461 [DRAW_BLACK_CIRCLE] = "* ",
5465 return draw_table[!is_locale_utf8()][ch];
5468 char *strreplace(const char *text, const char *old_string, const char *new_string) {
5471 size_t l, old_len, new_len;
5477 old_len = strlen(old_string);
5478 new_len = strlen(new_string);
5491 if (!startswith(f, old_string)) {
5497 nl = l - old_len + new_len;
5498 a = realloc(r, nl + 1);
5506 t = stpcpy(t, new_string);
5518 char *strip_tab_ansi(char **ibuf, size_t *_isz) {
5519 const char *i, *begin = NULL;
5524 } state = STATE_OTHER;
5526 size_t osz = 0, isz;
5532 /* Strips ANSI color and replaces TABs by 8 spaces */
5534 isz = _isz ? *_isz : strlen(*ibuf);
5536 f = open_memstream(&obuf, &osz);
5540 for (i = *ibuf; i < *ibuf + isz + 1; i++) {
5545 if (i >= *ibuf + isz) /* EOT */
5547 else if (*i == '\x1B')
5548 state = STATE_ESCAPE;
5549 else if (*i == '\t')
5556 if (i >= *ibuf + isz) { /* EOT */
5559 } else if (*i == '[') {
5560 state = STATE_BRACKET;
5565 state = STATE_OTHER;
5572 if (i >= *ibuf + isz || /* EOT */
5573 (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
5576 state = STATE_OTHER;
5578 } else if (*i == 'm')
5579 state = STATE_OTHER;
5601 int on_ac_power(void) {
5602 bool found_offline = false, found_online = false;
5603 _cleanup_closedir_ DIR *d = NULL;
5605 d = opendir("/sys/class/power_supply");
5611 _cleanup_close_ int fd = -1, device = -1;
5617 if (!de && errno != 0)
5623 if (ignore_file(de->d_name))
5626 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
5628 if (errno == ENOENT || errno == ENOTDIR)
5634 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
5636 if (errno == ENOENT)
5642 n = read(fd, contents, sizeof(contents));
5646 if (n != 6 || memcmp(contents, "Mains\n", 6))
5649 close_nointr_nofail(fd);
5650 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
5652 if (errno == ENOENT)
5658 n = read(fd, contents, sizeof(contents));
5662 if (n != 2 || contents[1] != '\n')
5665 if (contents[0] == '1') {
5666 found_online = true;
5668 } else if (contents[0] == '0')
5669 found_offline = true;
5674 return found_online || !found_offline;
5677 static int search_and_fopen_internal(const char *path, const char *mode, char **search, FILE **_f) {
5684 if (!path_strv_canonicalize_absolute_uniq(search, NULL))
5687 STRV_FOREACH(i, search) {
5688 _cleanup_free_ char *p = NULL;
5691 p = strjoin(*i, "/", path, NULL);
5701 if (errno != ENOENT)
5708 int search_and_fopen(const char *path, const char *mode, const char **search, FILE **_f) {
5709 _cleanup_strv_free_ char **copy = NULL;
5715 if (path_is_absolute(path)) {
5718 f = fopen(path, mode);
5727 copy = strv_copy((char**) search);
5731 return search_and_fopen_internal(path, mode, copy, _f);
5734 int search_and_fopen_nulstr(const char *path, const char *mode, const char *search, FILE **_f) {
5735 _cleanup_strv_free_ char **s = NULL;
5737 if (path_is_absolute(path)) {
5740 f = fopen(path, mode);
5749 s = strv_split_nulstr(search);
5753 return search_and_fopen_internal(path, mode, s, _f);
5756 char *strextend(char **x, ...) {
5763 l = f = *x ? strlen(*x) : 0;
5770 t = va_arg(ap, const char *);
5775 if (n > ((size_t) -1) - l) {
5784 r = realloc(*x, l+1);
5794 t = va_arg(ap, const char *);
5808 char *strrep(const char *s, unsigned n) {
5816 p = r = malloc(l * n + 1);
5820 for (i = 0; i < n; i++)
5827 void* greedy_realloc(void **p, size_t *allocated, size_t need) {
5834 if (*allocated >= need)
5837 a = MAX(64u, need * 2);
5839 /* check for overflows */
5852 void* greedy_realloc0(void **p, size_t *allocated, size_t need) {
5861 q = greedy_realloc(p, allocated, need);
5865 if (*allocated > prev)
5866 memzero(&q[prev], *allocated - prev);
5871 bool id128_is_valid(const char *s) {
5877 /* Simple formatted 128bit hex string */
5879 for (i = 0; i < l; i++) {
5882 if (!(c >= '0' && c <= '9') &&
5883 !(c >= 'a' && c <= 'z') &&
5884 !(c >= 'A' && c <= 'Z'))
5888 } else if (l == 36) {
5890 /* Formatted UUID */
5892 for (i = 0; i < l; i++) {
5895 if ((i == 8 || i == 13 || i == 18 || i == 23)) {
5899 if (!(c >= '0' && c <= '9') &&
5900 !(c >= 'a' && c <= 'z') &&
5901 !(c >= 'A' && c <= 'Z'))
5912 int split_pair(const char *s, const char *sep, char **l, char **r) {
5927 a = strndup(s, x - s);
5931 b = strdup(x + strlen(sep));
5943 int shall_restore_state(void) {
5944 _cleanup_free_ char *line = NULL;
5949 r = proc_cmdline(&line);
5952 if (r == 0) /* Container ... */
5957 FOREACH_WORD_QUOTED(w, l, line, state) {
5965 e = startswith(n, "systemd.restore_state=");
5969 k = parse_boolean(e);
5977 int proc_cmdline(char **ret) {
5980 if (detect_container(NULL) > 0) {
5981 char *buf = NULL, *p;
5984 r = read_full_file("/proc/1/cmdline", &buf, &sz);
5988 for (p = buf; p + 1 < buf + sz; p++)
5997 r = read_one_line_file("/proc/cmdline", ret);
6004 int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
6005 _cleanup_free_ char *line = NULL;
6012 r = proc_cmdline(&line);
6014 log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
6018 FOREACH_WORD_QUOTED(w, l, line, state) {
6019 char word[l+1], *value;
6024 /* Filter out arguments that are intended only for the
6026 if (!in_initrd() && startswith(word, "rd."))
6029 value = strchr(word, '=');
6033 r = parse_item(word, value);
6041 int container_get_leader(const char *machine, pid_t *pid) {
6042 _cleanup_free_ char *s = NULL, *class = NULL;
6050 p = strappenda("/run/systemd/machines/", machine);
6051 r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
6059 if (!streq_ptr(class, "container"))
6062 r = parse_pid(s, &leader);
6072 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *root_fd) {
6073 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1;
6074 const char *pidns, *mntns, *root;
6082 mntns = procfs_file_alloca(pid, "ns/mnt");
6083 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
6087 pidns = procfs_file_alloca(pid, "ns/pid");
6088 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
6092 root = procfs_file_alloca(pid, "root");
6093 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
6097 *pidns_fd = pidnsfd;
6098 *mntns_fd = mntnsfd;
6106 int namespace_enter(int pidns_fd, int mntns_fd, int root_fd) {
6107 assert(pidns_fd >= 0);
6108 assert(mntns_fd >= 0);
6109 assert(root_fd >= 0);
6111 if (setns(pidns_fd, CLONE_NEWPID) < 0)
6114 if (setns(mntns_fd, CLONE_NEWNS) < 0)
6117 if (fchdir(root_fd) < 0)
6120 if (chroot(".") < 0)
6123 if (setresgid(0, 0, 0) < 0)
6126 if (setresuid(0, 0, 0) < 0)
6132 bool pid_is_unwaited(pid_t pid) {
6133 /* Checks whether a PID is still valid at all, including a zombie */
6138 if (kill(pid, 0) >= 0)
6141 return errno != ESRCH;
6144 bool pid_is_alive(pid_t pid) {
6147 /* Checks whether a PID is still valid and not a zombie */
6152 r = get_process_state(pid);
6153 if (r == -ENOENT || r == 'Z')
6159 int getpeercred(int fd, struct ucred *ucred) {
6160 socklen_t n = sizeof(struct ucred);
6167 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
6171 if (n != sizeof(struct ucred))
6174 /* Check if the data is actually useful and not suppressed due
6175 * to namespacing issues */
6183 int getpeersec(int fd, char **ret) {
6195 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
6199 if (errno != ERANGE)
6206 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
6222 /* This is much like like mkostemp() but is subject to umask(). */
6223 int mkostemp_safe(char *pattern, int flags) {
6224 _cleanup_umask_ mode_t u;
6231 fd = mkostemp(pattern, flags);
6238 int open_tmpfile(const char *path, int flags) {
6245 /* Try O_TMPFILE first, if it is supported */
6246 fd = open(path, flags|O_TMPFILE, S_IRUSR|S_IWUSR);
6251 /* Fall back to unguessable name + unlinking */
6252 p = strappenda(path, "/systemd-tmp-XXXXXX");
6254 fd = mkostemp_safe(p, flags);
6262 int fd_warn_permissions(const char *path, int fd) {
6265 if (fstat(fd, &st) < 0)
6268 if (st.st_mode & 0111)
6269 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
6271 if (st.st_mode & 0002)
6272 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
6274 if (getpid() == 1 && (st.st_mode & 0044) != 0044)
6275 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);
6280 unsigned long personality_from_string(const char *p) {
6282 /* Parse a personality specifier. We introduce our own
6283 * identifiers that indicate specific ABIs, rather than just
6284 * hints regarding the register size, since we want to keep
6285 * things open for multiple locally supported ABIs for the
6286 * same register size. We try to reuse the ABI identifiers
6287 * used by libseccomp. */
6289 #if defined(__x86_64__)
6291 if (streq(p, "x86"))
6294 if (streq(p, "x86-64"))
6297 #elif defined(__i386__)
6299 if (streq(p, "x86"))
6303 /* personality(7) documents that 0xffffffffUL is used for
6304 * querying the current personality, hence let's use that here
6305 * as error indicator. */
6306 return 0xffffffffUL;
6309 const char* personality_to_string(unsigned long p) {
6311 #if defined(__x86_64__)
6313 if (p == PER_LINUX32)
6319 #elif defined(__i386__)
6328 uint64_t physical_memory(void) {
6331 /* We return this as uint64_t in case we are running as 32bit
6332 * process on a 64bit kernel with huge amounts of memory */
6334 mem = sysconf(_SC_PHYS_PAGES);
6337 return (uint64_t) mem * (uint64_t) page_size();
6340 char* mount_test_option(const char *haystack, const char *needle) {
6342 struct mntent me = {
6343 .mnt_opts = (char*) haystack
6348 /* Like glibc's hasmntopt(), but works on a string, not a
6354 return hasmntopt(&me, needle);