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 running_in_chroot(void) {
3202 struct stat a = {}, b = {};
3204 /* Only works as root */
3205 if (stat("/proc/1/root", &a) < 0)
3208 if (stat("/", &b) < 0)
3212 a.st_dev != b.st_dev ||
3213 a.st_ino != b.st_ino;
3216 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
3221 assert(percent <= 100);
3222 assert(new_length >= 3);
3224 if (old_length <= 3 || old_length <= new_length)
3225 return strndup(s, old_length);
3227 r = new0(char, new_length+1);
3231 x = (new_length * percent) / 100;
3233 if (x > new_length - 3)
3241 s + old_length - (new_length - x - 3),
3242 new_length - x - 3);
3247 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
3251 unsigned k, len, len2;
3254 assert(percent <= 100);
3255 assert(new_length >= 3);
3257 /* if no multibyte characters use ascii_ellipsize_mem for speed */
3258 if (ascii_is_valid(s))
3259 return ascii_ellipsize_mem(s, old_length, new_length, percent);
3261 if (old_length <= 3 || old_length <= new_length)
3262 return strndup(s, old_length);
3264 x = (new_length * percent) / 100;
3266 if (x > new_length - 3)
3270 for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
3273 c = utf8_encoded_to_unichar(i);
3276 k += unichar_iswide(c) ? 2 : 1;
3279 if (k > x) /* last character was wide and went over quota */
3282 for (j = s + old_length; k < new_length && j > i; ) {
3285 j = utf8_prev_char(j);
3286 c = utf8_encoded_to_unichar(j);
3289 k += unichar_iswide(c) ? 2 : 1;
3293 /* we don't actually need to ellipsize */
3295 return memdup(s, old_length + 1);
3297 /* make space for ellipsis */
3298 j = utf8_next_char(j);
3301 len2 = s + old_length - j;
3302 e = new(char, len + 3 + len2 + 1);
3307 printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
3308 old_length, new_length, x, len, len2, k);
3312 e[len] = 0xe2; /* tri-dot ellipsis: … */
3316 memcpy(e + len + 3, j, len2 + 1);
3321 char *ellipsize(const char *s, size_t length, unsigned percent) {
3322 return ellipsize_mem(s, strlen(s), length, percent);
3325 int touch(const char *path) {
3330 /* This just opens the file for writing, ensuring it
3331 * exists. It doesn't call utimensat() the way /usr/bin/touch
3334 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644);
3338 close_nointr_nofail(fd);
3342 char *unquote(const char *s, const char* quotes) {
3346 /* This is rather stupid, simply removes the heading and
3347 * trailing quotes if there is one. Doesn't care about
3348 * escaping or anything. We should make this smarter one
3355 if (strchr(quotes, s[0]) && s[l-1] == s[0])
3356 return strndup(s+1, l-2);
3361 char *normalize_env_assignment(const char *s) {
3362 _cleanup_free_ char *name = NULL, *value = NULL, *p = NULL;
3365 eq = strchr(s, '=');
3377 memmove(r, t, strlen(t) + 1);
3381 name = strndup(s, eq - s);
3389 value = unquote(strstrip(p), QUOTES);
3393 if (asprintf(&r, "%s=%s", strstrip(name), value) < 0)
3399 int wait_for_terminate(pid_t pid, siginfo_t *status) {
3410 if (waitid(P_PID, pid, status, WEXITED) < 0) {
3422 int wait_for_terminate_and_warn(const char *name, pid_t pid) {
3429 r = wait_for_terminate(pid, &status);
3431 log_warning("Failed to wait for %s: %s", name, strerror(-r));
3435 if (status.si_code == CLD_EXITED) {
3436 if (status.si_status != 0) {
3437 log_warning("%s failed with error code %i.", name, status.si_status);
3438 return status.si_status;
3441 log_debug("%s succeeded.", name);
3444 } else if (status.si_code == CLD_KILLED ||
3445 status.si_code == CLD_DUMPED) {
3447 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
3451 log_warning("%s failed due to unknown reason.", name);
3455 noreturn void freeze(void) {
3457 /* Make sure nobody waits for us on a socket anymore */
3458 close_all_fds(NULL, 0);
3466 bool null_or_empty(struct stat *st) {
3469 if (S_ISREG(st->st_mode) && st->st_size <= 0)
3472 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
3478 int null_or_empty_path(const char *fn) {
3483 if (stat(fn, &st) < 0)
3486 return null_or_empty(&st);
3489 DIR *xopendirat(int fd, const char *name, int flags) {
3493 assert(!(flags & O_CREAT));
3495 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
3501 close_nointr_nofail(nfd);
3508 int signal_from_string_try_harder(const char *s) {
3512 signo = signal_from_string(s);
3514 if (startswith(s, "SIG"))
3515 return signal_from_string(s+3);
3520 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
3521 _cleanup_free_ char *t = NULL, *u = NULL;
3524 u = unquote(tagvalue, "\"\'");
3528 enc_len = strlen(u) * 4 + 1;
3529 t = new(char, enc_len);
3533 if (encode_devnode_name(u, t, enc_len) < 0)
3536 return strjoin("/dev/disk/by-", by, "/", t, NULL);
3539 char *fstab_node_to_udev_node(const char *p) {
3542 if (startswith(p, "LABEL="))
3543 return tag_to_udev_node(p+6, "label");
3545 if (startswith(p, "UUID="))
3546 return tag_to_udev_node(p+5, "uuid");
3548 if (startswith(p, "PARTUUID="))
3549 return tag_to_udev_node(p+9, "partuuid");
3551 if (startswith(p, "PARTLABEL="))
3552 return tag_to_udev_node(p+10, "partlabel");
3557 bool tty_is_vc(const char *tty) {
3560 if (startswith(tty, "/dev/"))
3563 return vtnr_from_tty(tty) >= 0;
3566 bool tty_is_console(const char *tty) {
3569 if (startswith(tty, "/dev/"))
3572 return streq(tty, "console");
3575 int vtnr_from_tty(const char *tty) {
3580 if (startswith(tty, "/dev/"))
3583 if (!startswith(tty, "tty") )
3586 if (tty[3] < '0' || tty[3] > '9')
3589 r = safe_atoi(tty+3, &i);
3593 if (i < 0 || i > 63)
3599 char *resolve_dev_console(char **active) {
3602 /* Resolve where /dev/console is pointing to, if /sys is actually ours
3603 * (i.e. not read-only-mounted which is a sign for container setups) */
3605 if (path_is_read_only_fs("/sys") > 0)
3608 if (read_one_line_file("/sys/class/tty/console/active", active) < 0)
3611 /* If multiple log outputs are configured the last one is what
3612 * /dev/console points to */
3613 tty = strrchr(*active, ' ');
3619 if (streq(tty, "tty0")) {
3622 /* Get the active VC (e.g. tty1) */
3623 if (read_one_line_file("/sys/class/tty/tty0/active", &tmp) >= 0) {
3625 tty = *active = tmp;
3632 bool tty_is_vc_resolve(const char *tty) {
3633 _cleanup_free_ char *active = NULL;
3637 if (startswith(tty, "/dev/"))
3640 if (streq(tty, "console")) {
3641 tty = resolve_dev_console(&active);
3646 return tty_is_vc(tty);
3649 const char *default_term_for_tty(const char *tty) {
3652 return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102";
3655 bool dirent_is_file(const struct dirent *de) {
3658 if (ignore_file(de->d_name))
3661 if (de->d_type != DT_REG &&
3662 de->d_type != DT_LNK &&
3663 de->d_type != DT_UNKNOWN)
3669 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
3672 if (de->d_type != DT_REG &&
3673 de->d_type != DT_LNK &&
3674 de->d_type != DT_UNKNOWN)
3677 if (ignore_file_allow_backup(de->d_name))
3680 return endswith(de->d_name, suffix);
3683 void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv[]) {
3689 /* Executes all binaries in a directory in parallel and waits
3690 * for them to finish. Optionally a timeout is applied. */
3692 executor_pid = fork();
3693 if (executor_pid < 0) {
3694 log_error("Failed to fork: %m");
3697 } else if (executor_pid == 0) {
3698 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
3699 _cleanup_closedir_ DIR *_d = NULL;
3703 /* We fork this all off from a child process so that
3704 * we can somewhat cleanly make use of SIGALRM to set
3707 reset_all_signal_handlers();
3709 assert_se(sigemptyset(&ss) == 0);
3710 assert_se(sigprocmask(SIG_SETMASK, &ss, NULL) == 0);
3712 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
3715 d = _d = opendir(directory);
3717 if (errno == ENOENT)
3718 _exit(EXIT_SUCCESS);
3720 log_error("Failed to enumerate directory %s: %m", directory);
3721 _exit(EXIT_FAILURE);
3725 pids = hashmap_new(NULL, NULL);
3728 _exit(EXIT_FAILURE);
3731 FOREACH_DIRENT(de, d, break) {
3732 _cleanup_free_ char *path = NULL;
3735 if (!dirent_is_file(de))
3738 if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
3740 _exit(EXIT_FAILURE);
3745 log_error("Failed to fork: %m");
3747 } else if (pid == 0) {
3750 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
3760 log_error("Failed to execute %s: %m", path);
3761 _exit(EXIT_FAILURE);
3765 log_debug("Spawned %s as " PID_FMT ".", path, pid);
3767 r = hashmap_put(pids, UINT_TO_PTR(pid), path);
3770 _exit(EXIT_FAILURE);
3776 /* Abort execution of this process after the
3777 * timout. We simply rely on SIGALRM as default action
3778 * terminating the process, and turn on alarm(). */
3780 if (timeout != (usec_t) -1)
3781 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
3783 while (!hashmap_isempty(pids)) {
3784 _cleanup_free_ char *path = NULL;
3787 pid = PTR_TO_UINT(hashmap_first_key(pids));
3790 path = hashmap_remove(pids, UINT_TO_PTR(pid));
3793 wait_for_terminate_and_warn(path, pid);
3796 _exit(EXIT_SUCCESS);
3799 wait_for_terminate_and_warn(directory, executor_pid);
3802 int kill_and_sigcont(pid_t pid, int sig) {
3805 r = kill(pid, sig) < 0 ? -errno : 0;
3813 bool nulstr_contains(const char*nulstr, const char *needle) {
3819 NULSTR_FOREACH(i, nulstr)
3820 if (streq(i, needle))
3826 bool plymouth_running(void) {
3827 return access("/run/plymouth/pid", F_OK) >= 0;
3830 char* strshorten(char *s, size_t l) {
3839 static bool hostname_valid_char(char c) {
3841 (c >= 'a' && c <= 'z') ||
3842 (c >= 'A' && c <= 'Z') ||
3843 (c >= '0' && c <= '9') ||
3849 bool hostname_is_valid(const char *s) {
3856 for (p = s, dot = true; *p; p++) {
3863 if (!hostname_valid_char(*p))
3873 if (p-s > HOST_NAME_MAX)
3879 char* hostname_cleanup(char *s, bool lowercase) {
3883 for (p = s, d = s, dot = true; *p; p++) {
3890 } else if (hostname_valid_char(*p)) {
3891 *(d++) = lowercase ? tolower(*p) : *p;
3902 strshorten(s, HOST_NAME_MAX);
3907 int pipe_eof(int fd) {
3908 struct pollfd pollfd = {
3910 .events = POLLIN|POLLHUP,
3915 r = poll(&pollfd, 1, 0);
3922 return pollfd.revents & POLLHUP;
3925 int fd_wait_for_event(int fd, int event, usec_t t) {
3927 struct pollfd pollfd = {
3935 r = ppoll(&pollfd, 1, t == (usec_t) -1 ? NULL : timespec_store(&ts, t), NULL);
3942 return pollfd.revents;
3945 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
3956 t = new(char, strlen(path) + 1 + 6 + 1);
3960 fn = basename(path);
3964 stpcpy(stpcpy(t+k+1, fn), "XXXXXX");
3966 fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
3972 f = fdopen(fd, "we");
3985 int terminal_vhangup_fd(int fd) {
3988 if (ioctl(fd, TIOCVHANGUP) < 0)
3994 int terminal_vhangup(const char *name) {
3997 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4001 r = terminal_vhangup_fd(fd);
4002 close_nointr_nofail(fd);
4007 int vt_disallocate(const char *name) {
4011 /* Deallocate the VT if possible. If not possible
4012 * (i.e. because it is the active one), at least clear it
4013 * entirely (including the scrollback buffer) */
4015 if (!startswith(name, "/dev/"))
4018 if (!tty_is_vc(name)) {
4019 /* So this is not a VT. I guess we cannot deallocate
4020 * it then. But let's at least clear the screen */
4022 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4027 "\033[r" /* clear scrolling region */
4028 "\033[H" /* move home */
4029 "\033[2J", /* clear screen */
4031 close_nointr_nofail(fd);
4036 if (!startswith(name, "/dev/tty"))
4039 r = safe_atou(name+8, &u);
4046 /* Try to deallocate */
4047 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
4051 r = ioctl(fd, VT_DISALLOCATE, u);
4052 close_nointr_nofail(fd);
4060 /* Couldn't deallocate, so let's clear it fully with
4062 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4067 "\033[r" /* clear scrolling region */
4068 "\033[H" /* move home */
4069 "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
4071 close_nointr_nofail(fd);
4076 int copy_file(const char *from, const char *to, int flags) {
4077 _cleanup_close_ int fdf = -1;
4083 fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
4087 fdt = open(to, flags|O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644);
4095 n = read(fdf, buf, sizeof(buf));
4109 k = loop_write(fdt, buf, n, false);
4111 r = k < 0 ? k : (errno ? -errno : -EIO);
4120 r = close_nointr(fdt);
4130 int symlink_atomic(const char *from, const char *to) {
4132 _cleanup_free_ char *t;
4142 t = new(char, strlen(to) + 1 + 16 + 1);
4150 x = stpcpy(t+k+1, fn);
4153 for (i = 0; i < 16; i++) {
4154 *(x++) = hexchar(u & 0xF);
4160 if (symlink(from, t) < 0)
4163 if (rename(t, to) < 0) {
4172 bool display_is_local(const char *display) {
4176 display[0] == ':' &&
4177 display[1] >= '0' &&
4181 int socket_from_display(const char *display, char **path) {
4188 if (!display_is_local(display))
4191 k = strspn(display+1, "0123456789");
4193 f = new(char, sizeof("/tmp/.X11-unix/X") + k);
4197 c = stpcpy(f, "/tmp/.X11-unix/X");
4198 memcpy(c, display+1, k);
4207 const char **username,
4208 uid_t *uid, gid_t *gid,
4210 const char **shell) {
4218 /* We enforce some special rules for uid=0: in order to avoid
4219 * NSS lookups for root we hardcode its data. */
4221 if (streq(*username, "root") || streq(*username, "0")) {
4239 if (parse_uid(*username, &u) >= 0) {
4243 /* If there are multiple users with the same id, make
4244 * sure to leave $USER to the configured value instead
4245 * of the first occurrence in the database. However if
4246 * the uid was configured by a numeric uid, then let's
4247 * pick the real username from /etc/passwd. */
4249 *username = p->pw_name;
4252 p = getpwnam(*username);
4256 return errno > 0 ? -errno : -ESRCH;
4268 *shell = p->pw_shell;
4273 char* uid_to_name(uid_t uid) {
4278 return strdup("root");
4282 return strdup(p->pw_name);
4284 if (asprintf(&r, "%lu", (unsigned long) uid) < 0)
4290 char* gid_to_name(gid_t gid) {
4295 return strdup("root");
4299 return strdup(p->gr_name);
4301 if (asprintf(&r, "%lu", (unsigned long) gid) < 0)
4307 int get_group_creds(const char **groupname, gid_t *gid) {
4313 /* We enforce some special rules for gid=0: in order to avoid
4314 * NSS lookups for root we hardcode its data. */
4316 if (streq(*groupname, "root") || streq(*groupname, "0")) {
4317 *groupname = "root";
4325 if (parse_gid(*groupname, &id) >= 0) {
4330 *groupname = g->gr_name;
4333 g = getgrnam(*groupname);
4337 return errno > 0 ? -errno : -ESRCH;
4345 int in_gid(gid_t gid) {
4347 int ngroups_max, r, i;
4349 if (getgid() == gid)
4352 if (getegid() == gid)
4355 ngroups_max = sysconf(_SC_NGROUPS_MAX);
4356 assert(ngroups_max > 0);
4358 gids = alloca(sizeof(gid_t) * ngroups_max);
4360 r = getgroups(ngroups_max, gids);
4364 for (i = 0; i < r; i++)
4371 int in_group(const char *name) {
4375 r = get_group_creds(&name, &gid);
4382 int glob_exists(const char *path) {
4383 _cleanup_globfree_ glob_t g = {};
4389 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
4391 if (k == GLOB_NOMATCH)
4393 else if (k == GLOB_NOSPACE)
4396 return !strv_isempty(g.gl_pathv);
4398 return errno ? -errno : -EIO;
4401 int glob_extend(char ***strv, const char *path) {
4402 _cleanup_globfree_ glob_t g = {};
4407 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
4409 if (k == GLOB_NOMATCH)
4411 else if (k == GLOB_NOSPACE)
4413 else if (k != 0 || strv_isempty(g.gl_pathv))
4414 return errno ? -errno : -EIO;
4416 STRV_FOREACH(p, g.gl_pathv) {
4417 k = strv_extend(strv, *p);
4425 int dirent_ensure_type(DIR *d, struct dirent *de) {
4431 if (de->d_type != DT_UNKNOWN)
4434 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
4438 S_ISREG(st.st_mode) ? DT_REG :
4439 S_ISDIR(st.st_mode) ? DT_DIR :
4440 S_ISLNK(st.st_mode) ? DT_LNK :
4441 S_ISFIFO(st.st_mode) ? DT_FIFO :
4442 S_ISSOCK(st.st_mode) ? DT_SOCK :
4443 S_ISCHR(st.st_mode) ? DT_CHR :
4444 S_ISBLK(st.st_mode) ? DT_BLK :
4450 int in_search_path(const char *path, char **search) {
4452 _cleanup_free_ char *parent = NULL;
4455 r = path_get_parent(path, &parent);
4459 STRV_FOREACH(i, search)
4460 if (path_equal(parent, *i))
4466 int get_files_in_directory(const char *path, char ***list) {
4467 _cleanup_closedir_ DIR *d = NULL;
4468 size_t bufsize = 0, n = 0;
4469 _cleanup_strv_free_ char **l = NULL;
4473 /* Returns all files in a directory in *list, and the number
4474 * of files as return value. If list is NULL returns only the
4486 if (!de && errno != 0)
4491 dirent_ensure_type(d, de);
4493 if (!dirent_is_file(de))
4497 /* one extra slot is needed for the terminating NULL */
4498 if (!GREEDY_REALLOC(l, bufsize, n + 2))
4501 l[n] = strdup(de->d_name);
4512 l = NULL; /* avoid freeing */
4518 char *strjoin(const char *x, ...) {
4532 t = va_arg(ap, const char *);
4537 if (n > ((size_t) -1) - l) {
4561 t = va_arg(ap, const char *);
4575 bool is_main_thread(void) {
4576 static thread_local int cached = 0;
4578 if (_unlikely_(cached == 0))
4579 cached = getpid() == gettid() ? 1 : -1;
4584 int block_get_whole_disk(dev_t d, dev_t *ret) {
4591 /* If it has a queue this is good enough for us */
4592 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
4595 r = access(p, F_OK);
4603 /* If it is a partition find the originating device */
4604 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
4607 r = access(p, F_OK);
4613 /* Get parent dev_t */
4614 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
4617 r = read_one_line_file(p, &s);
4623 r = sscanf(s, "%u:%u", &m, &n);
4629 /* Only return this if it is really good enough for us. */
4630 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
4633 r = access(p, F_OK);
4637 *ret = makedev(m, n);
4644 int file_is_priv_sticky(const char *p) {
4649 if (lstat(p, &st) < 0)
4653 (st.st_uid == 0 || st.st_uid == getuid()) &&
4654 (st.st_mode & S_ISVTX);
4657 static const char *const ioprio_class_table[] = {
4658 [IOPRIO_CLASS_NONE] = "none",
4659 [IOPRIO_CLASS_RT] = "realtime",
4660 [IOPRIO_CLASS_BE] = "best-effort",
4661 [IOPRIO_CLASS_IDLE] = "idle"
4664 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
4666 static const char *const sigchld_code_table[] = {
4667 [CLD_EXITED] = "exited",
4668 [CLD_KILLED] = "killed",
4669 [CLD_DUMPED] = "dumped",
4670 [CLD_TRAPPED] = "trapped",
4671 [CLD_STOPPED] = "stopped",
4672 [CLD_CONTINUED] = "continued",
4675 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
4677 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
4678 [LOG_FAC(LOG_KERN)] = "kern",
4679 [LOG_FAC(LOG_USER)] = "user",
4680 [LOG_FAC(LOG_MAIL)] = "mail",
4681 [LOG_FAC(LOG_DAEMON)] = "daemon",
4682 [LOG_FAC(LOG_AUTH)] = "auth",
4683 [LOG_FAC(LOG_SYSLOG)] = "syslog",
4684 [LOG_FAC(LOG_LPR)] = "lpr",
4685 [LOG_FAC(LOG_NEWS)] = "news",
4686 [LOG_FAC(LOG_UUCP)] = "uucp",
4687 [LOG_FAC(LOG_CRON)] = "cron",
4688 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
4689 [LOG_FAC(LOG_FTP)] = "ftp",
4690 [LOG_FAC(LOG_LOCAL0)] = "local0",
4691 [LOG_FAC(LOG_LOCAL1)] = "local1",
4692 [LOG_FAC(LOG_LOCAL2)] = "local2",
4693 [LOG_FAC(LOG_LOCAL3)] = "local3",
4694 [LOG_FAC(LOG_LOCAL4)] = "local4",
4695 [LOG_FAC(LOG_LOCAL5)] = "local5",
4696 [LOG_FAC(LOG_LOCAL6)] = "local6",
4697 [LOG_FAC(LOG_LOCAL7)] = "local7"
4700 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
4702 static const char *const log_level_table[] = {
4703 [LOG_EMERG] = "emerg",
4704 [LOG_ALERT] = "alert",
4705 [LOG_CRIT] = "crit",
4707 [LOG_WARNING] = "warning",
4708 [LOG_NOTICE] = "notice",
4709 [LOG_INFO] = "info",
4710 [LOG_DEBUG] = "debug"
4713 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
4715 static const char* const sched_policy_table[] = {
4716 [SCHED_OTHER] = "other",
4717 [SCHED_BATCH] = "batch",
4718 [SCHED_IDLE] = "idle",
4719 [SCHED_FIFO] = "fifo",
4723 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
4725 static const char* const rlimit_table[_RLIMIT_MAX] = {
4726 [RLIMIT_CPU] = "LimitCPU",
4727 [RLIMIT_FSIZE] = "LimitFSIZE",
4728 [RLIMIT_DATA] = "LimitDATA",
4729 [RLIMIT_STACK] = "LimitSTACK",
4730 [RLIMIT_CORE] = "LimitCORE",
4731 [RLIMIT_RSS] = "LimitRSS",
4732 [RLIMIT_NOFILE] = "LimitNOFILE",
4733 [RLIMIT_AS] = "LimitAS",
4734 [RLIMIT_NPROC] = "LimitNPROC",
4735 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
4736 [RLIMIT_LOCKS] = "LimitLOCKS",
4737 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
4738 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
4739 [RLIMIT_NICE] = "LimitNICE",
4740 [RLIMIT_RTPRIO] = "LimitRTPRIO",
4741 [RLIMIT_RTTIME] = "LimitRTTIME"
4744 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
4746 static const char* const ip_tos_table[] = {
4747 [IPTOS_LOWDELAY] = "low-delay",
4748 [IPTOS_THROUGHPUT] = "throughput",
4749 [IPTOS_RELIABILITY] = "reliability",
4750 [IPTOS_LOWCOST] = "low-cost",
4753 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
4755 static const char *const __signal_table[] = {
4772 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
4783 [SIGVTALRM] = "VTALRM",
4785 [SIGWINCH] = "WINCH",
4791 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
4793 const char *signal_to_string(int signo) {
4794 static thread_local char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1];
4797 name = __signal_to_string(signo);
4801 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
4802 snprintf(buf, sizeof(buf), "RTMIN+%d", signo - SIGRTMIN);
4804 snprintf(buf, sizeof(buf), "%d", signo);
4809 int signal_from_string(const char *s) {
4814 signo = __signal_from_string(s);
4818 if (startswith(s, "RTMIN+")) {
4822 if (safe_atou(s, &u) >= 0) {
4823 signo = (int) u + offset;
4824 if (signo > 0 && signo < _NSIG)
4830 bool kexec_loaded(void) {
4831 bool loaded = false;
4834 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
4842 int strdup_or_null(const char *a, char **b) {
4860 int prot_from_flags(int flags) {
4862 switch (flags & O_ACCMODE) {
4871 return PROT_READ|PROT_WRITE;
4878 char *format_bytes(char *buf, size_t l, off_t t) {
4881 static const struct {
4885 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
4886 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
4887 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
4888 { "G", 1024ULL*1024ULL*1024ULL },
4889 { "M", 1024ULL*1024ULL },
4893 for (i = 0; i < ELEMENTSOF(table); i++) {
4895 if (t >= table[i].factor) {
4898 (unsigned long long) (t / table[i].factor),
4899 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
4906 snprintf(buf, l, "%lluB", (unsigned long long) t);
4914 void* memdup(const void *p, size_t l) {
4927 int fd_inc_sndbuf(int fd, size_t n) {
4929 socklen_t l = sizeof(value);
4931 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
4932 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
4935 /* If we have the privileges we will ignore the kernel limit. */
4938 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
4939 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
4945 int fd_inc_rcvbuf(int fd, size_t n) {
4947 socklen_t l = sizeof(value);
4949 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
4950 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
4953 /* If we have the privileges we will ignore the kernel limit. */
4956 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
4957 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
4962 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
4963 pid_t parent_pid, agent_pid;
4965 bool stdout_is_tty, stderr_is_tty;
4973 parent_pid = getpid();
4975 /* Spawns a temporary TTY agent, making sure it goes away when
4982 if (agent_pid != 0) {
4989 * Make sure the agent goes away when the parent dies */
4990 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
4991 _exit(EXIT_FAILURE);
4993 /* Check whether our parent died before we were able
4994 * to set the death signal */
4995 if (getppid() != parent_pid)
4996 _exit(EXIT_SUCCESS);
4998 /* Don't leak fds to the agent */
4999 close_all_fds(except, n_except);
5001 stdout_is_tty = isatty(STDOUT_FILENO);
5002 stderr_is_tty = isatty(STDERR_FILENO);
5004 if (!stdout_is_tty || !stderr_is_tty) {
5005 /* Detach from stdout/stderr. and reopen
5006 * /dev/tty for them. This is important to
5007 * ensure that when systemctl is started via
5008 * popen() or a similar call that expects to
5009 * read EOF we actually do generate EOF and
5010 * not delay this indefinitely by because we
5011 * keep an unused copy of stdin around. */
5012 fd = open("/dev/tty", O_WRONLY);
5014 log_error("Failed to open /dev/tty: %m");
5015 _exit(EXIT_FAILURE);
5019 dup2(fd, STDOUT_FILENO);
5022 dup2(fd, STDERR_FILENO);
5028 /* Count arguments */
5030 for (n = 0; va_arg(ap, char*); n++)
5035 l = alloca(sizeof(char *) * (n + 1));
5037 /* Fill in arguments */
5039 for (i = 0; i <= n; i++)
5040 l[i] = va_arg(ap, char*);
5044 _exit(EXIT_FAILURE);
5047 int setrlimit_closest(int resource, const struct rlimit *rlim) {
5048 struct rlimit highest, fixed;
5052 if (setrlimit(resource, rlim) >= 0)
5058 /* So we failed to set the desired setrlimit, then let's try
5059 * to get as close as we can */
5060 assert_se(getrlimit(resource, &highest) == 0);
5062 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
5063 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
5065 if (setrlimit(resource, &fixed) < 0)
5071 int getenv_for_pid(pid_t pid, const char *field, char **_value) {
5072 _cleanup_fclose_ FILE *f = NULL;
5083 path = procfs_file_alloca(pid, "environ");
5085 f = fopen(path, "re");
5093 char line[LINE_MAX];
5096 for (i = 0; i < sizeof(line)-1; i++) {
5100 if (_unlikely_(c == EOF)) {
5110 if (memcmp(line, field, l) == 0 && line[l] == '=') {
5111 value = strdup(line + l + 1);
5125 bool is_valid_documentation_url(const char *url) {
5128 if (startswith(url, "http://") && url[7])
5131 if (startswith(url, "https://") && url[8])
5134 if (startswith(url, "file:") && url[5])
5137 if (startswith(url, "info:") && url[5])
5140 if (startswith(url, "man:") && url[4])
5146 bool in_initrd(void) {
5147 static int saved = -1;
5153 /* We make two checks here:
5155 * 1. the flag file /etc/initrd-release must exist
5156 * 2. the root file system must be a memory file system
5158 * The second check is extra paranoia, since misdetecting an
5159 * initrd can have bad bad consequences due the initrd
5160 * emptying when transititioning to the main systemd.
5163 saved = access("/etc/initrd-release", F_OK) >= 0 &&
5164 statfs("/", &s) >= 0 &&
5165 is_temporary_fs(&s);
5170 void warn_melody(void) {
5171 _cleanup_close_ int fd = -1;
5173 fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
5177 /* Yeah, this is synchronous. Kinda sucks. But well... */
5179 ioctl(fd, KIOCSOUND, (int)(1193180/440));
5180 usleep(125*USEC_PER_MSEC);
5182 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5183 usleep(125*USEC_PER_MSEC);
5185 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5186 usleep(125*USEC_PER_MSEC);
5188 ioctl(fd, KIOCSOUND, 0);
5191 int make_console_stdio(void) {
5194 /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
5196 fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1);
5198 log_error("Failed to acquire terminal: %s", strerror(-fd));
5204 log_error("Failed to duplicate terminal fd: %s", strerror(-r));
5211 int get_home_dir(char **_h) {
5219 /* Take the user specified one */
5230 /* Hardcode home directory for root to avoid NSS */
5233 h = strdup("/root");
5241 /* Check the database... */
5245 return errno > 0 ? -errno : -ESRCH;
5247 if (!path_is_absolute(p->pw_dir))
5250 h = strdup(p->pw_dir);
5258 int get_shell(char **_s) {
5266 /* Take the user specified one */
5267 e = getenv("SHELL");
5277 /* Hardcode home directory for root to avoid NSS */
5280 s = strdup("/bin/sh");
5288 /* Check the database... */
5292 return errno > 0 ? -errno : -ESRCH;
5294 if (!path_is_absolute(p->pw_shell))
5297 s = strdup(p->pw_shell);
5305 bool filename_is_safe(const char *p) {
5319 if (strlen(p) > FILENAME_MAX)
5325 bool string_is_safe(const char *p) {
5330 for (t = p; *t; t++) {
5331 if (*t > 0 && *t < ' ')
5334 if (strchr("\\\"\'", *t))
5342 * Check if a string contains control characters.
5343 * Spaces and tabs are not considered control characters.
5345 bool string_has_cc(const char *p) {
5350 for (t = p; *t; t++)
5351 if (*t > 0 && *t < ' ' && *t != '\t')
5357 bool path_is_safe(const char *p) {
5362 if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
5365 if (strlen(p) > PATH_MAX)
5368 /* The following two checks are not really dangerous, but hey, they still are confusing */
5369 if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
5372 if (strstr(p, "//"))
5378 /* hey glibc, APIs with callbacks without a user pointer are so useless */
5379 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
5380 int (*compar) (const void *, const void *, void *), void *arg) {
5389 p = (void *)(((const char *) base) + (idx * size));
5390 comparison = compar(key, p, arg);
5393 else if (comparison > 0)
5401 bool is_locale_utf8(void) {
5403 static int cached_answer = -1;
5405 if (cached_answer >= 0)
5408 if (!setlocale(LC_ALL, "")) {
5409 cached_answer = true;
5413 set = nl_langinfo(CODESET);
5415 cached_answer = true;
5419 if (streq(set, "UTF-8")) {
5420 cached_answer = true;
5424 /* For LC_CTYPE=="C" return true, because CTYPE is effectly
5425 * unset and everything can do to UTF-8 nowadays. */
5426 set = setlocale(LC_CTYPE, NULL);
5428 cached_answer = true;
5432 /* Check result, but ignore the result if C was set
5436 !getenv("LC_ALL") &&
5437 !getenv("LC_CTYPE") &&
5441 return (bool) cached_answer;
5444 const char *draw_special_char(DrawSpecialChar ch) {
5445 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
5447 [DRAW_TREE_VERT] = "\342\224\202 ", /* │ */
5448 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
5449 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
5450 [DRAW_TREE_SPACE] = " ", /* */
5451 [DRAW_TRIANGULAR_BULLET] = "\342\200\243 ", /* ‣ */
5452 [DRAW_BLACK_CIRCLE] = "\342\227\217 ", /* ● */
5454 /* ASCII fallback */ {
5455 [DRAW_TREE_VERT] = "| ",
5456 [DRAW_TREE_BRANCH] = "|-",
5457 [DRAW_TREE_RIGHT] = "`-",
5458 [DRAW_TREE_SPACE] = " ",
5459 [DRAW_TRIANGULAR_BULLET] = "> ",
5460 [DRAW_BLACK_CIRCLE] = "* ",
5464 return draw_table[!is_locale_utf8()][ch];
5467 char *strreplace(const char *text, const char *old_string, const char *new_string) {
5470 size_t l, old_len, new_len;
5476 old_len = strlen(old_string);
5477 new_len = strlen(new_string);
5490 if (!startswith(f, old_string)) {
5496 nl = l - old_len + new_len;
5497 a = realloc(r, nl + 1);
5505 t = stpcpy(t, new_string);
5517 char *strip_tab_ansi(char **ibuf, size_t *_isz) {
5518 const char *i, *begin = NULL;
5523 } state = STATE_OTHER;
5525 size_t osz = 0, isz;
5531 /* Strips ANSI color and replaces TABs by 8 spaces */
5533 isz = _isz ? *_isz : strlen(*ibuf);
5535 f = open_memstream(&obuf, &osz);
5539 for (i = *ibuf; i < *ibuf + isz + 1; i++) {
5544 if (i >= *ibuf + isz) /* EOT */
5546 else if (*i == '\x1B')
5547 state = STATE_ESCAPE;
5548 else if (*i == '\t')
5555 if (i >= *ibuf + isz) { /* EOT */
5558 } else if (*i == '[') {
5559 state = STATE_BRACKET;
5564 state = STATE_OTHER;
5571 if (i >= *ibuf + isz || /* EOT */
5572 (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
5575 state = STATE_OTHER;
5577 } else if (*i == 'm')
5578 state = STATE_OTHER;
5600 int on_ac_power(void) {
5601 bool found_offline = false, found_online = false;
5602 _cleanup_closedir_ DIR *d = NULL;
5604 d = opendir("/sys/class/power_supply");
5610 _cleanup_close_ int fd = -1, device = -1;
5616 if (!de && errno != 0)
5622 if (ignore_file(de->d_name))
5625 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
5627 if (errno == ENOENT || errno == ENOTDIR)
5633 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
5635 if (errno == ENOENT)
5641 n = read(fd, contents, sizeof(contents));
5645 if (n != 6 || memcmp(contents, "Mains\n", 6))
5648 close_nointr_nofail(fd);
5649 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
5651 if (errno == ENOENT)
5657 n = read(fd, contents, sizeof(contents));
5661 if (n != 2 || contents[1] != '\n')
5664 if (contents[0] == '1') {
5665 found_online = true;
5667 } else if (contents[0] == '0')
5668 found_offline = true;
5673 return found_online || !found_offline;
5676 static int search_and_fopen_internal(const char *path, const char *mode, char **search, FILE **_f) {
5683 if (!path_strv_canonicalize_absolute_uniq(search, NULL))
5686 STRV_FOREACH(i, search) {
5687 _cleanup_free_ char *p = NULL;
5690 p = strjoin(*i, "/", path, NULL);
5700 if (errno != ENOENT)
5707 int search_and_fopen(const char *path, const char *mode, const char **search, FILE **_f) {
5708 _cleanup_strv_free_ char **copy = NULL;
5714 if (path_is_absolute(path)) {
5717 f = fopen(path, mode);
5726 copy = strv_copy((char**) search);
5730 return search_and_fopen_internal(path, mode, copy, _f);
5733 int search_and_fopen_nulstr(const char *path, const char *mode, const char *search, FILE **_f) {
5734 _cleanup_strv_free_ char **s = NULL;
5736 if (path_is_absolute(path)) {
5739 f = fopen(path, mode);
5748 s = strv_split_nulstr(search);
5752 return search_and_fopen_internal(path, mode, s, _f);
5755 char *strextend(char **x, ...) {
5762 l = f = *x ? strlen(*x) : 0;
5769 t = va_arg(ap, const char *);
5774 if (n > ((size_t) -1) - l) {
5783 r = realloc(*x, l+1);
5793 t = va_arg(ap, const char *);
5807 char *strrep(const char *s, unsigned n) {
5815 p = r = malloc(l * n + 1);
5819 for (i = 0; i < n; i++)
5826 void* greedy_realloc(void **p, size_t *allocated, size_t need) {
5833 if (*allocated >= need)
5836 a = MAX(64u, need * 2);
5838 /* check for overflows */
5851 void* greedy_realloc0(void **p, size_t *allocated, size_t need) {
5860 q = greedy_realloc(p, allocated, need);
5864 if (*allocated > prev)
5865 memzero(&q[prev], *allocated - prev);
5870 bool id128_is_valid(const char *s) {
5876 /* Simple formatted 128bit hex string */
5878 for (i = 0; i < l; i++) {
5881 if (!(c >= '0' && c <= '9') &&
5882 !(c >= 'a' && c <= 'z') &&
5883 !(c >= 'A' && c <= 'Z'))
5887 } else if (l == 36) {
5889 /* Formatted UUID */
5891 for (i = 0; i < l; i++) {
5894 if ((i == 8 || i == 13 || i == 18 || i == 23)) {
5898 if (!(c >= '0' && c <= '9') &&
5899 !(c >= 'a' && c <= 'z') &&
5900 !(c >= 'A' && c <= 'Z'))
5911 int split_pair(const char *s, const char *sep, char **l, char **r) {
5926 a = strndup(s, x - s);
5930 b = strdup(x + strlen(sep));
5942 int shall_restore_state(void) {
5943 _cleanup_free_ char *line = NULL;
5948 r = proc_cmdline(&line);
5951 if (r == 0) /* Container ... */
5956 FOREACH_WORD_QUOTED(w, l, line, state) {
5964 e = startswith(n, "systemd.restore_state=");
5968 k = parse_boolean(e);
5976 int proc_cmdline(char **ret) {
5979 if (detect_container(NULL) > 0) {
5980 char *buf = NULL, *p;
5983 r = read_full_file("/proc/1/cmdline", &buf, &sz);
5987 for (p = buf; p + 1 < buf + sz; p++)
5996 r = read_one_line_file("/proc/cmdline", ret);
6003 int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
6004 _cleanup_free_ char *line = NULL;
6011 r = proc_cmdline(&line);
6013 log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
6017 FOREACH_WORD_QUOTED(w, l, line, state) {
6018 char word[l+1], *value;
6023 /* Filter out arguments that are intended only for the
6025 if (!in_initrd() && startswith(word, "rd."))
6028 value = strchr(word, '=');
6032 r = parse_item(word, value);
6040 int container_get_leader(const char *machine, pid_t *pid) {
6041 _cleanup_free_ char *s = NULL, *class = NULL;
6049 p = strappenda("/run/systemd/machines/", machine);
6050 r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
6058 if (!streq_ptr(class, "container"))
6061 r = parse_pid(s, &leader);
6071 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *root_fd) {
6072 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1;
6073 const char *pidns, *mntns, *root;
6081 mntns = procfs_file_alloca(pid, "ns/mnt");
6082 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
6086 pidns = procfs_file_alloca(pid, "ns/pid");
6087 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
6091 root = procfs_file_alloca(pid, "root");
6092 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
6096 *pidns_fd = pidnsfd;
6097 *mntns_fd = mntnsfd;
6105 int namespace_enter(int pidns_fd, int mntns_fd, int root_fd) {
6106 assert(pidns_fd >= 0);
6107 assert(mntns_fd >= 0);
6108 assert(root_fd >= 0);
6110 if (setns(pidns_fd, CLONE_NEWPID) < 0)
6113 if (setns(mntns_fd, CLONE_NEWNS) < 0)
6116 if (fchdir(root_fd) < 0)
6119 if (chroot(".") < 0)
6122 if (setresgid(0, 0, 0) < 0)
6125 if (setresuid(0, 0, 0) < 0)
6131 bool pid_is_unwaited(pid_t pid) {
6132 /* Checks whether a PID is still valid at all, including a zombie */
6137 if (kill(pid, 0) >= 0)
6140 return errno != ESRCH;
6143 bool pid_is_alive(pid_t pid) {
6146 /* Checks whether a PID is still valid and not a zombie */
6151 r = get_process_state(pid);
6152 if (r == -ENOENT || r == 'Z')
6158 int getpeercred(int fd, struct ucred *ucred) {
6159 socklen_t n = sizeof(struct ucred);
6166 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
6170 if (n != sizeof(struct ucred))
6173 /* Check if the data is actually useful and not suppressed due
6174 * to namespacing issues */
6182 int getpeersec(int fd, char **ret) {
6194 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
6198 if (errno != ERANGE)
6205 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
6221 /* This is much like like mkostemp() but is subject to umask(). */
6222 int mkostemp_safe(char *pattern, int flags) {
6223 _cleanup_umask_ mode_t u;
6230 fd = mkostemp(pattern, flags);
6237 int open_tmpfile(const char *path, int flags) {
6244 /* Try O_TMPFILE first, if it is supported */
6245 fd = open(path, flags|O_TMPFILE, S_IRUSR|S_IWUSR);
6250 /* Fall back to unguessable name + unlinking */
6251 p = strappenda(path, "/systemd-tmp-XXXXXX");
6253 fd = mkostemp_safe(p, flags);
6261 int fd_warn_permissions(const char *path, int fd) {
6264 if (fstat(fd, &st) < 0)
6267 if (st.st_mode & 0111)
6268 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
6270 if (st.st_mode & 0002)
6271 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
6273 if (getpid() == 1 && (st.st_mode & 0044) != 0044)
6274 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);
6279 unsigned long personality_from_string(const char *p) {
6281 /* Parse a personality specifier. We introduce our own
6282 * identifiers that indicate specific ABIs, rather than just
6283 * hints regarding the register size, since we want to keep
6284 * things open for multiple locally supported ABIs for the
6285 * same register size. We try to reuse the ABI identifiers
6286 * used by libseccomp. */
6288 #if defined(__x86_64__)
6290 if (streq(p, "x86"))
6293 if (streq(p, "x86-64"))
6296 #elif defined(__i386__)
6298 if (streq(p, "x86"))
6302 /* personality(7) documents that 0xffffffffUL is used for
6303 * querying the current personality, hence let's use that here
6304 * as error indicator. */
6305 return 0xffffffffUL;
6308 const char* personality_to_string(unsigned long p) {
6310 #if defined(__x86_64__)
6312 if (p == PER_LINUX32)
6318 #elif defined(__i386__)
6327 uint64_t physical_memory(void) {
6330 /* We return this as uint64_t in case we are running as 32bit
6331 * process on a 64bit kernel with huge amounts of memory */
6333 mem = sysconf(_SC_PHYS_PAGES);
6336 return (uint64_t) mem * (uint64_t) page_size();
6339 char* mount_test_option(const char *haystack, const char *needle) {
6341 struct mntent me = {
6342 .mnt_opts = (char*) haystack
6347 /* Like glibc's hasmntopt(), but works on a string, not a
6353 return hasmntopt(&me, needle);