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>
46 #include <sys/prctl.h>
47 #include <sys/utsname.h>
49 #include <netinet/ip.h>
58 #include <linux/magic.h>
67 #include "path-util.h"
68 #include "exit-status.h"
72 char **saved_argv = NULL;
74 size_t page_size(void) {
75 static __thread size_t pgsz = 0;
78 if (_likely_(pgsz > 0))
81 assert_se((r = sysconf(_SC_PAGESIZE)) > 0);
88 bool streq_ptr(const char *a, const char *b) {
90 /* Like streq(), but tries to make sense of NULL pointers */
101 usec_t now(clockid_t clock_id) {
104 assert_se(clock_gettime(clock_id, &ts) == 0);
106 return timespec_load(&ts);
109 dual_timestamp* dual_timestamp_get(dual_timestamp *ts) {
112 ts->realtime = now(CLOCK_REALTIME);
113 ts->monotonic = now(CLOCK_MONOTONIC);
118 dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) {
127 delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
129 ts->monotonic = now(CLOCK_MONOTONIC);
131 if ((int64_t) ts->monotonic > delta)
132 ts->monotonic -= delta;
140 usec_t timespec_load(const struct timespec *ts) {
144 (usec_t) ts->tv_sec * USEC_PER_SEC +
145 (usec_t) ts->tv_nsec / NSEC_PER_USEC;
148 struct timespec *timespec_store(struct timespec *ts, usec_t u) {
151 ts->tv_sec = (time_t) (u / USEC_PER_SEC);
152 ts->tv_nsec = (long int) ((u % USEC_PER_SEC) * NSEC_PER_USEC);
157 usec_t timeval_load(const struct timeval *tv) {
161 (usec_t) tv->tv_sec * USEC_PER_SEC +
162 (usec_t) tv->tv_usec;
165 struct timeval *timeval_store(struct timeval *tv, usec_t u) {
168 tv->tv_sec = (time_t) (u / USEC_PER_SEC);
169 tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC);
174 bool endswith(const char *s, const char *postfix) {
181 pl = strlen(postfix);
189 return memcmp(s + sl - pl, postfix, pl) == 0;
192 bool startswith(const char *s, const char *prefix) {
207 return memcmp(s, prefix, pl) == 0;
210 bool startswith_no_case(const char *s, const char *prefix) {
226 for(i = 0; i < pl; ++i) {
227 if (tolower(s[i]) != tolower(prefix[i]))
234 bool first_word(const char *s, const char *word) {
249 if (memcmp(s, word, wl) != 0)
253 strchr(WHITESPACE, s[wl]);
256 int close_nointr(int fd) {
271 void close_nointr_nofail(int fd) {
272 int saved_errno = errno;
274 /* like close_nointr() but cannot fail, and guarantees errno
277 assert_se(close_nointr(fd) == 0);
282 void close_many(const int fds[], unsigned n_fd) {
285 for (i = 0; i < n_fd; i++)
286 close_nointr_nofail(fds[i]);
289 int parse_boolean(const char *v) {
292 if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
294 else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
300 int parse_pid(const char *s, pid_t* ret_pid) {
301 unsigned long ul = 0;
308 if ((r = safe_atolu(s, &ul)) < 0)
313 if ((unsigned long) pid != ul)
323 int parse_uid(const char *s, uid_t* ret_uid) {
324 unsigned long ul = 0;
331 if ((r = safe_atolu(s, &ul)) < 0)
336 if ((unsigned long) uid != ul)
343 int safe_atou(const char *s, unsigned *ret_u) {
351 l = strtoul(s, &x, 0);
353 if (!x || *x || errno)
354 return errno ? -errno : -EINVAL;
356 if ((unsigned long) (unsigned) l != l)
359 *ret_u = (unsigned) l;
363 int safe_atoi(const char *s, int *ret_i) {
371 l = strtol(s, &x, 0);
373 if (!x || *x || errno)
374 return errno ? -errno : -EINVAL;
376 if ((long) (int) l != l)
383 int safe_atollu(const char *s, long long unsigned *ret_llu) {
385 unsigned long long l;
391 l = strtoull(s, &x, 0);
393 if (!x || *x || errno)
394 return errno ? -errno : -EINVAL;
400 int safe_atolli(const char *s, long long int *ret_lli) {
408 l = strtoll(s, &x, 0);
410 if (!x || *x || errno)
411 return errno ? -errno : -EINVAL;
417 /* Split a string into words. */
418 char *split(const char *c, size_t *l, const char *separator, char **state) {
421 current = *state ? *state : (char*) c;
423 if (!*current || *c == 0)
426 current += strspn(current, separator);
427 *l = strcspn(current, separator);
430 return (char*) current;
433 /* Split a string into words, but consider strings enclosed in '' and
434 * "" as words even if they include spaces. */
435 char *split_quoted(const char *c, size_t *l, char **state) {
437 bool escaped = false;
439 current = *state ? *state : (char*) c;
441 if (!*current || *c == 0)
444 current += strspn(current, WHITESPACE);
446 if (*current == '\'') {
449 for (e = current; *e; e++) {
459 *state = *e == 0 ? e : e+1;
460 } else if (*current == '\"') {
463 for (e = current; *e; e++) {
473 *state = *e == 0 ? e : e+1;
475 for (e = current; *e; e++) {
480 else if (strchr(WHITESPACE, *e))
487 return (char*) current;
490 int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
493 char fn[PATH_MAX], line[LINE_MAX], *p;
499 assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1));
502 if (!(f = fopen(fn, "re")))
505 if (!(fgets(line, sizeof(line), f))) {
506 r = feof(f) ? -EIO : -errno;
513 /* Let's skip the pid and comm fields. The latter is enclosed
514 * in () but does not escape any () in its value, so let's
515 * skip over it manually */
517 if (!(p = strrchr(line, ')')))
528 if ((long unsigned) (pid_t) ppid != ppid)
531 *_ppid = (pid_t) ppid;
536 int get_starttime_of_pid(pid_t pid, unsigned long long *st) {
539 char fn[PATH_MAX], line[LINE_MAX], *p;
544 assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1));
547 if (!(f = fopen(fn, "re")))
550 if (!(fgets(line, sizeof(line), f))) {
551 r = feof(f) ? -EIO : -errno;
558 /* Let's skip the pid and comm fields. The latter is enclosed
559 * in () but does not escape any () in its value, so let's
560 * skip over it manually */
562 if (!(p = strrchr(line, ')')))
583 "%*d " /* priority */
585 "%*d " /* num_threads */
586 "%*d " /* itrealvalue */
587 "%llu " /* starttime */,
594 int write_one_line_file(const char *fn, const char *line) {
606 if (fputs(line, f) < 0) {
611 if (!endswith(line, "\n"))
629 int fchmod_umask(int fd, mode_t m) {
634 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
640 int write_one_line_file_atomic(const char *fn, const char *line) {
648 r = fopen_temporary(fn, &f, &p);
652 fchmod_umask(fileno(f), 0644);
655 if (fputs(line, f) < 0) {
660 if (!endswith(line, "\n"))
671 if (rename(p, fn) < 0)
687 int read_one_line_file(const char *fn, char **line) {
690 char t[LINE_MAX], *c;
699 if (!fgets(t, sizeof(t), f)) {
725 int read_full_file(const char *fn, char **contents, size_t *size) {
732 if (!(f = fopen(fn, "re")))
735 if (fstat(fileno(f), &st) < 0) {
741 if (st.st_size > 4*1024*1024) {
746 n = st.st_size > 0 ? st.st_size : LINE_MAX;
753 if (!(t = realloc(buf, n+1))) {
759 k = fread(buf + l, 1, n - l, f);
774 if (n > 4*1024*1024) {
798 const char *separator, ...) {
801 char *contents = NULL, *p;
806 if ((r = read_full_file(fname, &contents, NULL)) < 0)
811 const char *key = NULL;
813 p += strspn(p, separator);
814 p += strspn(p, WHITESPACE);
819 if (!strchr(COMMENTS, *p)) {
823 va_start(ap, separator);
824 while ((key = va_arg(ap, char *))) {
828 value = va_arg(ap, char **);
831 if (strncmp(p, key, n) != 0 ||
836 n = strcspn(p, separator);
839 strchr(QUOTES, p[0]) &&
841 v = strndup(p+1, n-2);
852 /* return empty value strings as NULL */
869 p += strcspn(p, separator);
888 if (!(f = fopen(fname, "re")))
892 char l[LINE_MAX], *p, *u;
895 if (!fgets(l, sizeof(l), f)) {
908 if (strchr(COMMENTS, *p))
911 if (!(u = normalize_env_assignment(p))) {
916 t = strv_append(m, u);
942 int write_env_file(const char *fname, char **l) {
947 r = fopen_temporary(fname, &f, &p);
951 fchmod_umask(fileno(f), 0644);
967 if (rename(p, fname) < 0)
982 char *truncate_nl(char *s) {
985 s[strcspn(s, NEWLINE)] = 0;
989 int get_process_comm(pid_t pid, char **name) {
995 r = read_one_line_file("/proc/self/comm", name);
998 if (asprintf(&p, "/proc/%lu/comm", (unsigned long) pid) < 0)
1001 r = read_one_line_file(p, name);
1008 int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
1015 assert(max_length > 0);
1019 f = fopen("/proc/self/cmdline", "re");
1022 if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
1032 r = new(char, max_length);
1040 while ((c = getc(f)) != EOF) {
1062 size_t n = MIN(left-1, 3U);
1063 memcpy(k, "...", n);
1070 /* Kernel threads have no argv[] */
1080 h = get_process_comm(pid, &t);
1084 r = strjoin("[", t, "]", NULL);
1095 int is_kernel_thread(pid_t pid) {
1105 if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
1114 count = fread(&c, 1, 1, f);
1118 /* Kernel threads have an empty cmdline */
1121 return eof ? 1 : -errno;
1126 int get_process_exe(pid_t pid, char **name) {
1132 r = readlink_malloc("/proc/self/exe", name);
1135 if (asprintf(&p, "/proc/%lu/exe", (unsigned long) pid) < 0)
1138 r = readlink_malloc(p, name);
1145 int get_process_uid(pid_t pid, uid_t *uid) {
1155 if (asprintf(&p, "/proc/%lu/status", (unsigned long) pid) < 0)
1165 char line[LINE_MAX], *l;
1167 if (!fgets(line, sizeof(line), f)) {
1177 if (startswith(l, "Uid:")) {
1179 l += strspn(l, WHITESPACE);
1181 l[strcspn(l, WHITESPACE)] = 0;
1183 r = parse_uid(l, uid);
1196 char *strnappend(const char *s, const char *suffix, size_t b) {
1204 return strndup(suffix, b);
1214 if (!(r = new(char, a+b+1)))
1218 memcpy(r+a, suffix, b);
1224 char *strappend(const char *s, const char *suffix) {
1225 return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
1228 int readlink_malloc(const char *p, char **r) {
1238 if (!(c = new(char, l)))
1241 if ((n = readlink(p, c, l-1)) < 0) {
1247 if ((size_t) n < l-1) {
1258 int readlink_and_make_absolute(const char *p, char **r) {
1265 if ((j = readlink_malloc(p, &target)) < 0)
1268 k = file_in_same_dir(p, target);
1278 int readlink_and_canonicalize(const char *p, char **r) {
1285 j = readlink_and_make_absolute(p, &t);
1289 s = canonicalize_file_name(t);
1296 path_kill_slashes(*r);
1301 int reset_all_signal_handlers(void) {
1304 for (sig = 1; sig < _NSIG; sig++) {
1305 struct sigaction sa;
1307 if (sig == SIGKILL || sig == SIGSTOP)
1311 sa.sa_handler = SIG_DFL;
1312 sa.sa_flags = SA_RESTART;
1314 /* On Linux the first two RT signals are reserved by
1315 * glibc, and sigaction() will return EINVAL for them. */
1316 if ((sigaction(sig, &sa, NULL) < 0))
1317 if (errno != EINVAL)
1324 char *strstrip(char *s) {
1327 /* Drops trailing whitespace. Modifies the string in
1328 * place. Returns pointer to first non-space character */
1330 s += strspn(s, WHITESPACE);
1332 for (e = strchr(s, 0); e > s; e --)
1333 if (!strchr(WHITESPACE, e[-1]))
1341 char *delete_chars(char *s, const char *bad) {
1344 /* Drops all whitespace, regardless where in the string */
1346 for (f = s, t = s; *f; f++) {
1347 if (strchr(bad, *f))
1358 bool in_charset(const char *s, const char* charset) {
1364 for (i = s; *i; i++)
1365 if (!strchr(charset, *i))
1371 char *file_in_same_dir(const char *path, const char *filename) {
1378 /* This removes the last component of path and appends
1379 * filename, unless the latter is absolute anyway or the
1382 if (path_is_absolute(filename))
1383 return strdup(filename);
1385 if (!(e = strrchr(path, '/')))
1386 return strdup(filename);
1388 k = strlen(filename);
1389 if (!(r = new(char, e-path+1+k+1)))
1392 memcpy(r, path, e-path+1);
1393 memcpy(r+(e-path)+1, filename, k+1);
1398 int rmdir_parents(const char *path, const char *stop) {
1407 /* Skip trailing slashes */
1408 while (l > 0 && path[l-1] == '/')
1414 /* Skip last component */
1415 while (l > 0 && path[l-1] != '/')
1418 /* Skip trailing slashes */
1419 while (l > 0 && path[l-1] == '/')
1425 if (!(t = strndup(path, l)))
1428 if (path_startswith(stop, t)) {
1437 if (errno != ENOENT)
1445 char hexchar(int x) {
1446 static const char table[16] = "0123456789abcdef";
1448 return table[x & 15];
1451 int unhexchar(char c) {
1453 if (c >= '0' && c <= '9')
1456 if (c >= 'a' && c <= 'f')
1457 return c - 'a' + 10;
1459 if (c >= 'A' && c <= 'F')
1460 return c - 'A' + 10;
1465 char octchar(int x) {
1466 return '0' + (x & 7);
1469 int unoctchar(char c) {
1471 if (c >= '0' && c <= '7')
1477 char decchar(int x) {
1478 return '0' + (x % 10);
1481 int undecchar(char c) {
1483 if (c >= '0' && c <= '9')
1489 char *cescape(const char *s) {
1495 /* Does C style string escaping. */
1497 r = new(char, strlen(s)*4 + 1);
1501 for (f = s, t = r; *f; f++)
1547 /* For special chars we prefer octal over
1548 * hexadecimal encoding, simply because glib's
1549 * g_strescape() does the same */
1550 if ((*f < ' ') || (*f >= 127)) {
1552 *(t++) = octchar((unsigned char) *f >> 6);
1553 *(t++) = octchar((unsigned char) *f >> 3);
1554 *(t++) = octchar((unsigned char) *f);
1565 char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix) {
1572 /* Undoes C style string escaping, and optionally prefixes it. */
1574 pl = prefix ? strlen(prefix) : 0;
1576 r = new(char, pl+length+1);
1581 memcpy(r, prefix, pl);
1583 for (f = s, t = r + pl; f < s + length; f++) {
1626 /* This is an extension of the XDG syntax files */
1631 /* hexadecimal encoding */
1634 a = unhexchar(f[1]);
1635 b = unhexchar(f[2]);
1637 if (a < 0 || b < 0) {
1638 /* Invalid escape code, let's take it literal then */
1642 *(t++) = (char) ((a << 4) | b);
1657 /* octal encoding */
1660 a = unoctchar(f[0]);
1661 b = unoctchar(f[1]);
1662 c = unoctchar(f[2]);
1664 if (a < 0 || b < 0 || c < 0) {
1665 /* Invalid escape code, let's take it literal then */
1669 *(t++) = (char) ((a << 6) | (b << 3) | c);
1677 /* premature end of string.*/
1682 /* Invalid escape code, let's take it literal then */
1694 char *cunescape_length(const char *s, size_t length) {
1695 return cunescape_length_with_prefix(s, length, NULL);
1698 char *cunescape(const char *s) {
1701 return cunescape_length(s, strlen(s));
1704 char *xescape(const char *s, const char *bad) {
1708 /* Escapes all chars in bad, in addition to \ and all special
1709 * chars, in \xFF style escaping. May be reversed with
1712 if (!(r = new(char, strlen(s)*4+1)))
1715 for (f = s, t = r; *f; f++) {
1717 if ((*f < ' ') || (*f >= 127) ||
1718 (*f == '\\') || strchr(bad, *f)) {
1721 *(t++) = hexchar(*f >> 4);
1722 *(t++) = hexchar(*f);
1732 char *bus_path_escape(const char *s) {
1738 /* Escapes all chars that D-Bus' object path cannot deal
1739 * with. Can be reverse with bus_path_unescape() */
1741 if (!(r = new(char, strlen(s)*3+1)))
1744 for (f = s, t = r; *f; f++) {
1746 if (!(*f >= 'A' && *f <= 'Z') &&
1747 !(*f >= 'a' && *f <= 'z') &&
1748 !(*f >= '0' && *f <= '9')) {
1750 *(t++) = hexchar(*f >> 4);
1751 *(t++) = hexchar(*f);
1761 char *bus_path_unescape(const char *f) {
1766 if (!(r = strdup(f)))
1769 for (t = r; *f; f++) {
1774 if ((a = unhexchar(f[1])) < 0 ||
1775 (b = unhexchar(f[2])) < 0) {
1776 /* Invalid escape code, let's take it literal then */
1779 *(t++) = (char) ((a << 4) | b);
1791 char *ascii_strlower(char *t) {
1796 for (p = t; *p; p++)
1797 if (*p >= 'A' && *p <= 'Z')
1798 *p = *p - 'A' + 'a';
1803 bool ignore_file(const char *filename) {
1807 filename[0] == '.' ||
1808 streq(filename, "lost+found") ||
1809 streq(filename, "aquota.user") ||
1810 streq(filename, "aquota.group") ||
1811 endswith(filename, "~") ||
1812 endswith(filename, ".rpmnew") ||
1813 endswith(filename, ".rpmsave") ||
1814 endswith(filename, ".rpmorig") ||
1815 endswith(filename, ".dpkg-old") ||
1816 endswith(filename, ".dpkg-new") ||
1817 endswith(filename, ".swp");
1820 int fd_nonblock(int fd, bool nonblock) {
1825 if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
1829 flags |= O_NONBLOCK;
1831 flags &= ~O_NONBLOCK;
1833 if (fcntl(fd, F_SETFL, flags) < 0)
1839 int fd_cloexec(int fd, bool cloexec) {
1844 if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
1848 flags |= FD_CLOEXEC;
1850 flags &= ~FD_CLOEXEC;
1852 if (fcntl(fd, F_SETFD, flags) < 0)
1858 static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
1861 assert(n_fdset == 0 || fdset);
1863 for (i = 0; i < n_fdset; i++)
1870 int close_all_fds(const int except[], unsigned n_except) {
1875 assert(n_except == 0 || except);
1877 d = opendir("/proc/self/fd");
1882 /* When /proc isn't available (for example in chroots)
1883 * the fallback is brute forcing through the fd
1886 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
1887 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
1889 if (fd_in_set(fd, except, n_except))
1892 if (close_nointr(fd) < 0)
1893 if (errno != EBADF && r == 0)
1900 while ((de = readdir(d))) {
1903 if (ignore_file(de->d_name))
1906 if (safe_atoi(de->d_name, &fd) < 0)
1907 /* Let's better ignore this, just in case */
1916 if (fd_in_set(fd, except, n_except))
1919 if (close_nointr(fd) < 0) {
1920 /* Valgrind has its own FD and doesn't want to have it closed */
1921 if (errno != EBADF && r == 0)
1930 bool chars_intersect(const char *a, const char *b) {
1933 /* Returns true if any of the chars in a are in b. */
1934 for (p = a; *p; p++)
1941 char *format_timestamp(char *buf, size_t l, usec_t t) {
1951 sec = (time_t) (t / USEC_PER_SEC);
1953 if (strftime(buf, l, "%a, %d %b %Y %H:%M:%S %z", localtime_r(&sec, &tm)) <= 0)
1959 char *format_timestamp_pretty(char *buf, size_t l, usec_t t) {
1962 n = now(CLOCK_REALTIME);
1964 if (t <= 0 || t > n || t + USEC_PER_DAY*7 <= t)
1969 if (d >= USEC_PER_YEAR)
1970 snprintf(buf, l, "%llu years and %llu months ago",
1971 (unsigned long long) (d / USEC_PER_YEAR),
1972 (unsigned long long) ((d % USEC_PER_YEAR) / USEC_PER_MONTH));
1973 else if (d >= USEC_PER_MONTH)
1974 snprintf(buf, l, "%llu months and %llu days ago",
1975 (unsigned long long) (d / USEC_PER_MONTH),
1976 (unsigned long long) ((d % USEC_PER_MONTH) / USEC_PER_DAY));
1977 else if (d >= USEC_PER_WEEK)
1978 snprintf(buf, l, "%llu weeks and %llu days ago",
1979 (unsigned long long) (d / USEC_PER_WEEK),
1980 (unsigned long long) ((d % USEC_PER_WEEK) / USEC_PER_DAY));
1981 else if (d >= 2*USEC_PER_DAY)
1982 snprintf(buf, l, "%llu days ago", (unsigned long long) (d / USEC_PER_DAY));
1983 else if (d >= 25*USEC_PER_HOUR)
1984 snprintf(buf, l, "1 day and %lluh ago",
1985 (unsigned long long) ((d - USEC_PER_DAY) / USEC_PER_HOUR));
1986 else if (d >= 6*USEC_PER_HOUR)
1987 snprintf(buf, l, "%lluh ago",
1988 (unsigned long long) (d / USEC_PER_HOUR));
1989 else if (d >= USEC_PER_HOUR)
1990 snprintf(buf, l, "%lluh %llumin ago",
1991 (unsigned long long) (d / USEC_PER_HOUR),
1992 (unsigned long long) ((d % USEC_PER_HOUR) / USEC_PER_MINUTE));
1993 else if (d >= 5*USEC_PER_MINUTE)
1994 snprintf(buf, l, "%llumin ago",
1995 (unsigned long long) (d / USEC_PER_MINUTE));
1996 else if (d >= USEC_PER_MINUTE)
1997 snprintf(buf, l, "%llumin %llus ago",
1998 (unsigned long long) (d / USEC_PER_MINUTE),
1999 (unsigned long long) ((d % USEC_PER_MINUTE) / USEC_PER_SEC));
2000 else if (d >= USEC_PER_SEC)
2001 snprintf(buf, l, "%llus ago",
2002 (unsigned long long) (d / USEC_PER_SEC));
2003 else if (d >= USEC_PER_MSEC)
2004 snprintf(buf, l, "%llums ago",
2005 (unsigned long long) (d / USEC_PER_MSEC));
2007 snprintf(buf, l, "%lluus ago",
2008 (unsigned long long) d);
2010 snprintf(buf, l, "now");
2016 char *format_timespan(char *buf, size_t l, usec_t t) {
2017 static const struct {
2021 { "w", USEC_PER_WEEK },
2022 { "d", USEC_PER_DAY },
2023 { "h", USEC_PER_HOUR },
2024 { "min", USEC_PER_MINUTE },
2025 { "s", USEC_PER_SEC },
2026 { "ms", USEC_PER_MSEC },
2036 if (t == (usec_t) -1)
2040 snprintf(p, l, "0");
2045 /* The result of this function can be parsed with parse_usec */
2047 for (i = 0; i < ELEMENTSOF(table); i++) {
2051 if (t < table[i].usec)
2057 k = snprintf(p, l, "%s%llu%s", p > buf ? " " : "", (unsigned long long) (t / table[i].usec), table[i].suffix);
2058 n = MIN((size_t) k, l);
2071 bool fstype_is_network(const char *fstype) {
2072 static const char * const table[] = {
2084 for (i = 0; i < ELEMENTSOF(table); i++)
2085 if (streq(table[i], fstype))
2094 if ((fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0)
2099 TIOCL_GETKMSGREDIRECT,
2103 if (ioctl(fd, TIOCLINUX, tiocl) < 0) {
2108 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
2111 if (ioctl(fd, VT_ACTIVATE, vt) < 0)
2115 close_nointr_nofail(fd);
2119 int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
2120 struct termios old_termios, new_termios;
2122 char line[LINE_MAX];
2127 if (tcgetattr(fileno(f), &old_termios) >= 0) {
2128 new_termios = old_termios;
2130 new_termios.c_lflag &= ~ICANON;
2131 new_termios.c_cc[VMIN] = 1;
2132 new_termios.c_cc[VTIME] = 0;
2134 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
2137 if (t != (usec_t) -1) {
2138 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
2139 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
2144 k = fread(&c, 1, 1, f);
2146 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
2152 *need_nl = c != '\n';
2159 if (t != (usec_t) -1)
2160 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
2163 if (!fgets(line, sizeof(line), f))
2168 if (strlen(line) != 1)
2178 int ask(char *ret, const char *replies, const char *text, ...) {
2185 on_tty = isatty(STDOUT_FILENO);
2191 bool need_nl = true;
2194 fputs(ANSI_HIGHLIGHT_ON, stdout);
2201 fputs(ANSI_HIGHLIGHT_OFF, stdout);
2205 r = read_one_char(stdin, &c, (usec_t) -1, &need_nl);
2208 if (r == -EBADMSG) {
2209 puts("Bad input, please try again.");
2220 if (strchr(replies, c)) {
2225 puts("Read unexpected character, please try again.");
2229 int reset_terminal_fd(int fd, bool switch_to_text) {
2230 struct termios termios;
2233 /* Set terminal to some sane defaults */
2237 /* We leave locked terminal attributes untouched, so that
2238 * Plymouth may set whatever it wants to set, and we don't
2239 * interfere with that. */
2241 /* Disable exclusive mode, just in case */
2242 ioctl(fd, TIOCNXCL);
2244 /* Switch to text mode */
2246 ioctl(fd, KDSETMODE, KD_TEXT);
2248 /* Enable console unicode mode */
2249 ioctl(fd, KDSKBMODE, K_UNICODE);
2251 if (tcgetattr(fd, &termios) < 0) {
2256 /* We only reset the stuff that matters to the software. How
2257 * hardware is set up we don't touch assuming that somebody
2258 * else will do that for us */
2260 termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
2261 termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
2262 termios.c_oflag |= ONLCR;
2263 termios.c_cflag |= CREAD;
2264 termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
2266 termios.c_cc[VINTR] = 03; /* ^C */
2267 termios.c_cc[VQUIT] = 034; /* ^\ */
2268 termios.c_cc[VERASE] = 0177;
2269 termios.c_cc[VKILL] = 025; /* ^X */
2270 termios.c_cc[VEOF] = 04; /* ^D */
2271 termios.c_cc[VSTART] = 021; /* ^Q */
2272 termios.c_cc[VSTOP] = 023; /* ^S */
2273 termios.c_cc[VSUSP] = 032; /* ^Z */
2274 termios.c_cc[VLNEXT] = 026; /* ^V */
2275 termios.c_cc[VWERASE] = 027; /* ^W */
2276 termios.c_cc[VREPRINT] = 022; /* ^R */
2277 termios.c_cc[VEOL] = 0;
2278 termios.c_cc[VEOL2] = 0;
2280 termios.c_cc[VTIME] = 0;
2281 termios.c_cc[VMIN] = 1;
2283 if (tcsetattr(fd, TCSANOW, &termios) < 0)
2287 /* Just in case, flush all crap out */
2288 tcflush(fd, TCIOFLUSH);
2293 int reset_terminal(const char *name) {
2296 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2300 r = reset_terminal_fd(fd, true);
2301 close_nointr_nofail(fd);
2306 int open_terminal(const char *name, int mode) {
2311 * If a TTY is in the process of being closed opening it might
2312 * cause EIO. This is horribly awful, but unlikely to be
2313 * changed in the kernel. Hence we work around this problem by
2314 * retrying a couple of times.
2316 * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
2320 fd = open(name, mode);
2327 /* Max 1s in total */
2331 usleep(50 * USEC_PER_MSEC);
2340 close_nointr_nofail(fd);
2345 close_nointr_nofail(fd);
2352 int flush_fd(int fd) {
2353 struct pollfd pollfd;
2357 pollfd.events = POLLIN;
2364 if ((r = poll(&pollfd, 1, 0)) < 0) {
2375 if ((l = read(fd, buf, sizeof(buf))) < 0) {
2380 if (errno == EAGAIN)
2391 int acquire_terminal(
2395 bool ignore_tiocstty_eperm,
2398 int fd = -1, notify = -1, r = 0, wd = -1;
2400 struct sigaction sa_old, sa_new;
2404 /* We use inotify to be notified when the tty is closed. We
2405 * create the watch before checking if we can actually acquire
2406 * it, so that we don't lose any event.
2408 * Note: strictly speaking this actually watches for the
2409 * device being closed, it does *not* really watch whether a
2410 * tty loses its controlling process. However, unless some
2411 * rogue process uses TIOCNOTTY on /dev/tty *after* closing
2412 * its tty otherwise this will not become a problem. As long
2413 * as the administrator makes sure not configure any service
2414 * on the same tty as an untrusted user this should not be a
2415 * problem. (Which he probably should not do anyway.) */
2417 if (timeout != (usec_t) -1)
2418 ts = now(CLOCK_MONOTONIC);
2420 if (!fail && !force) {
2421 notify = inotify_init1(IN_CLOEXEC | (timeout != (usec_t) -1 ? IN_NONBLOCK : 0));
2427 wd = inotify_add_watch(notify, name, IN_CLOSE);
2436 r = flush_fd(notify);
2441 /* We pass here O_NOCTTY only so that we can check the return
2442 * value TIOCSCTTY and have a reliable way to figure out if we
2443 * successfully became the controlling process of the tty */
2444 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2448 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2449 * if we already own the tty. */
2451 sa_new.sa_handler = SIG_IGN;
2452 sa_new.sa_flags = SA_RESTART;
2453 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2455 /* First, try to get the tty */
2456 if (ioctl(fd, TIOCSCTTY, force) < 0)
2459 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2461 /* Sometimes it makes sense to ignore TIOCSCTTY
2462 * returning EPERM, i.e. when very likely we already
2463 * are have this controlling terminal. */
2464 if (r < 0 && r == -EPERM && ignore_tiocstty_eperm)
2467 if (r < 0 && (force || fail || r != -EPERM)) {
2476 assert(notify >= 0);
2479 uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
2481 struct inotify_event *e;
2483 if (timeout != (usec_t) -1) {
2486 n = now(CLOCK_MONOTONIC);
2487 if (ts + timeout < n) {
2492 r = fd_wait_for_event(fd, POLLIN, ts + timeout - n);
2502 l = read(notify, inotify_buffer, sizeof(inotify_buffer));
2505 if (errno == EINTR || errno == EAGAIN)
2512 e = (struct inotify_event*) inotify_buffer;
2517 if (e->wd != wd || !(e->mask & IN_CLOSE)) {
2522 step = sizeof(struct inotify_event) + e->len;
2523 assert(step <= (size_t) l);
2525 e = (struct inotify_event*) ((uint8_t*) e + step);
2532 /* We close the tty fd here since if the old session
2533 * ended our handle will be dead. It's important that
2534 * we do this after sleeping, so that we don't enter
2535 * an endless loop. */
2536 close_nointr_nofail(fd);
2540 close_nointr_nofail(notify);
2542 r = reset_terminal_fd(fd, true);
2544 log_warning("Failed to reset terminal: %s", strerror(-r));
2550 close_nointr_nofail(fd);
2553 close_nointr_nofail(notify);
2558 int release_terminal(void) {
2560 struct sigaction sa_old, sa_new;
2562 if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC)) < 0)
2565 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2566 * by our own TIOCNOTTY */
2569 sa_new.sa_handler = SIG_IGN;
2570 sa_new.sa_flags = SA_RESTART;
2571 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2573 if (ioctl(fd, TIOCNOTTY) < 0)
2576 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2578 close_nointr_nofail(fd);
2582 int sigaction_many(const struct sigaction *sa, ...) {
2587 while ((sig = va_arg(ap, int)) > 0)
2588 if (sigaction(sig, sa, NULL) < 0)
2595 int ignore_signals(int sig, ...) {
2596 struct sigaction sa;
2601 sa.sa_handler = SIG_IGN;
2602 sa.sa_flags = SA_RESTART;
2604 if (sigaction(sig, &sa, NULL) < 0)
2608 while ((sig = va_arg(ap, int)) > 0)
2609 if (sigaction(sig, &sa, NULL) < 0)
2616 int default_signals(int sig, ...) {
2617 struct sigaction sa;
2622 sa.sa_handler = SIG_DFL;
2623 sa.sa_flags = SA_RESTART;
2625 if (sigaction(sig, &sa, NULL) < 0)
2629 while ((sig = va_arg(ap, int)) > 0)
2630 if (sigaction(sig, &sa, NULL) < 0)
2637 int close_pipe(int p[]) {
2643 a = close_nointr(p[0]);
2648 b = close_nointr(p[1]);
2652 return a < 0 ? a : b;
2655 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2664 while (nbytes > 0) {
2667 if ((k = read(fd, p, nbytes)) <= 0) {
2669 if (k < 0 && errno == EINTR)
2672 if (k < 0 && errno == EAGAIN && do_poll) {
2673 struct pollfd pollfd;
2677 pollfd.events = POLLIN;
2679 if (poll(&pollfd, 1, -1) < 0) {
2683 return n > 0 ? n : -errno;
2686 if (pollfd.revents != POLLIN)
2687 return n > 0 ? n : -EIO;
2692 return n > 0 ? n : (k < 0 ? -errno : 0);
2703 ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2712 while (nbytes > 0) {
2715 k = write(fd, p, nbytes);
2718 if (k < 0 && errno == EINTR)
2721 if (k < 0 && errno == EAGAIN && do_poll) {
2722 struct pollfd pollfd;
2726 pollfd.events = POLLOUT;
2728 if (poll(&pollfd, 1, -1) < 0) {
2732 return n > 0 ? n : -errno;
2735 if (pollfd.revents != POLLOUT)
2736 return n > 0 ? n : -EIO;
2741 return n > 0 ? n : (k < 0 ? -errno : 0);
2752 int parse_usec(const char *t, usec_t *usec) {
2753 static const struct {
2757 { "sec", USEC_PER_SEC },
2758 { "s", USEC_PER_SEC },
2759 { "min", USEC_PER_MINUTE },
2760 { "hr", USEC_PER_HOUR },
2761 { "h", USEC_PER_HOUR },
2762 { "d", USEC_PER_DAY },
2763 { "w", USEC_PER_WEEK },
2764 { "msec", USEC_PER_MSEC },
2765 { "ms", USEC_PER_MSEC },
2766 { "m", USEC_PER_MINUTE },
2769 { "", USEC_PER_SEC }, /* default is sec */
2785 l = strtoll(p, &e, 10);
2796 e += strspn(e, WHITESPACE);
2798 for (i = 0; i < ELEMENTSOF(table); i++)
2799 if (startswith(e, table[i].suffix)) {
2800 r += (usec_t) l * table[i].usec;
2801 p = e + strlen(table[i].suffix);
2805 if (i >= ELEMENTSOF(table))
2815 int parse_nsec(const char *t, nsec_t *nsec) {
2816 static const struct {
2820 { "sec", NSEC_PER_SEC },
2821 { "s", NSEC_PER_SEC },
2822 { "min", NSEC_PER_MINUTE },
2823 { "hr", NSEC_PER_HOUR },
2824 { "h", NSEC_PER_HOUR },
2825 { "d", NSEC_PER_DAY },
2826 { "w", NSEC_PER_WEEK },
2827 { "msec", NSEC_PER_MSEC },
2828 { "ms", NSEC_PER_MSEC },
2829 { "m", NSEC_PER_MINUTE },
2830 { "usec", NSEC_PER_USEC },
2831 { "us", NSEC_PER_USEC },
2834 { "", 1ULL }, /* default is nsec */
2850 l = strtoll(p, &e, 10);
2861 e += strspn(e, WHITESPACE);
2863 for (i = 0; i < ELEMENTSOF(table); i++)
2864 if (startswith(e, table[i].suffix)) {
2865 r += (nsec_t) l * table[i].nsec;
2866 p = e + strlen(table[i].suffix);
2870 if (i >= ELEMENTSOF(table))
2880 int parse_bytes(const char *t, off_t *bytes) {
2881 static const struct {
2887 { "M", 1024ULL*1024ULL },
2888 { "G", 1024ULL*1024ULL*1024ULL },
2889 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2890 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2891 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2908 l = strtoll(p, &e, 10);
2919 e += strspn(e, WHITESPACE);
2921 for (i = 0; i < ELEMENTSOF(table); i++)
2922 if (startswith(e, table[i].suffix)) {
2923 r += (off_t) l * table[i].factor;
2924 p = e + strlen(table[i].suffix);
2928 if (i >= ELEMENTSOF(table))
2938 int make_stdio(int fd) {
2943 r = dup2(fd, STDIN_FILENO);
2944 s = dup2(fd, STDOUT_FILENO);
2945 t = dup2(fd, STDERR_FILENO);
2948 close_nointr_nofail(fd);
2950 if (r < 0 || s < 0 || t < 0)
2953 fd_cloexec(STDIN_FILENO, false);
2954 fd_cloexec(STDOUT_FILENO, false);
2955 fd_cloexec(STDERR_FILENO, false);
2960 int make_null_stdio(void) {
2963 null_fd = open("/dev/null", O_RDWR|O_NOCTTY);
2967 return make_stdio(null_fd);
2970 bool is_device_path(const char *path) {
2972 /* Returns true on paths that refer to a device, either in
2973 * sysfs or in /dev */
2976 path_startswith(path, "/dev/") ||
2977 path_startswith(path, "/sys/");
2980 int dir_is_empty(const char *path) {
2983 struct dirent buf, *de;
2985 if (!(d = opendir(path)))
2989 if ((r = readdir_r(d, &buf, &de)) > 0) {
2999 if (!ignore_file(de->d_name)) {
3009 unsigned long long random_ull(void) {
3014 fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
3018 r = loop_read(fd, &ull, sizeof(ull), true);
3019 close_nointr_nofail(fd);
3021 if (r != sizeof(ull))
3027 return random() * RAND_MAX + random();
3030 void rename_process(const char name[8]) {
3033 /* This is a like a poor man's setproctitle(). It changes the
3034 * comm field, argv[0], and also the glibc's internally used
3035 * name of the process. For the first one a limit of 16 chars
3036 * applies, to the second one usually one of 10 (i.e. length
3037 * of "/sbin/init"), to the third one one of 7 (i.e. length of
3038 * "systemd"). If you pass a longer string it will be
3041 prctl(PR_SET_NAME, name);
3043 if (program_invocation_name)
3044 strncpy(program_invocation_name, name, strlen(program_invocation_name));
3046 if (saved_argc > 0) {
3050 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
3052 for (i = 1; i < saved_argc; i++) {
3056 memset(saved_argv[i], 0, strlen(saved_argv[i]));
3061 void sigset_add_many(sigset_t *ss, ...) {
3068 while ((sig = va_arg(ap, int)) > 0)
3069 assert_se(sigaddset(ss, sig) == 0);
3073 char* gethostname_malloc(void) {
3076 assert_se(uname(&u) >= 0);
3078 if (!isempty(u.nodename) && !streq(u.nodename, "(none)"))
3079 return strdup(u.nodename);
3081 return strdup(u.sysname);
3084 bool hostname_is_set(void) {
3087 assert_se(uname(&u) >= 0);
3089 return !isempty(u.nodename) && !streq(u.nodename, "(none)");
3093 static char *lookup_uid(uid_t uid) {
3096 struct passwd pwbuf, *pw = NULL;
3098 /* Shortcut things to avoid NSS lookups */
3100 return strdup("root");
3102 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
3106 buf = malloc(bufsize);
3110 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw) {
3111 name = strdup(pw->pw_name);
3118 if (asprintf(&name, "%lu", (unsigned long) uid) < 0)
3124 char* getlogname_malloc(void) {
3128 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
3133 return lookup_uid(uid);
3136 char *getusername_malloc(void) {
3143 return lookup_uid(getuid());
3146 int getttyname_malloc(int fd, char **r) {
3147 char path[PATH_MAX], *c;
3152 if ((k = ttyname_r(fd, path, sizeof(path))) != 0)
3157 if (!(c = strdup(startswith(path, "/dev/") ? path + 5 : path)))
3164 int getttyname_harder(int fd, char **r) {
3168 if ((k = getttyname_malloc(fd, &s)) < 0)
3171 if (streq(s, "tty")) {
3173 return get_ctty(0, NULL, r);
3180 int get_ctty_devnr(pid_t pid, dev_t *d) {
3182 char line[LINE_MAX], *p, *fn;
3183 unsigned long ttynr;
3186 if (asprintf(&fn, "/proc/%lu/stat", (unsigned long) (pid <= 0 ? getpid() : pid)) < 0)
3189 f = fopen(fn, "re");
3194 if (!fgets(line, sizeof(line), f)) {
3195 k = feof(f) ? -EIO : -errno;
3202 p = strrchr(line, ')');
3212 "%*d " /* session */
3221 int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
3223 char fn[PATH_MAX], *s, *b, *p;
3228 k = get_ctty_devnr(pid, &devnr);
3232 snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
3235 if ((k = readlink_malloc(fn, &s)) < 0) {
3240 /* This is an ugly hack */
3241 if (major(devnr) == 136) {
3242 if (asprintf(&b, "pts/%lu", (unsigned long) minor(devnr)) < 0)
3252 /* Probably something like the ptys which have no
3253 * symlink in /dev/char. Let's return something
3254 * vaguely useful. */
3256 if (!(b = strdup(fn + 5)))
3266 if (startswith(s, "/dev/"))
3268 else if (startswith(s, "../"))
3286 int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
3292 /* This returns the first error we run into, but nevertheless
3293 * tries to go on. This closes the passed fd. */
3297 close_nointr_nofail(fd);
3299 return errno == ENOENT ? 0 : -errno;
3303 struct dirent buf, *de;
3304 bool is_dir, keep_around;
3308 r = readdir_r(d, &buf, &de);
3309 if (r != 0 && ret == 0) {
3317 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
3320 if (de->d_type == DT_UNKNOWN ||
3322 (de->d_type == DT_DIR && root_dev)) {
3323 if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
3324 if (ret == 0 && errno != ENOENT)
3329 is_dir = S_ISDIR(st.st_mode);
3332 (st.st_uid == 0 || st.st_uid == getuid()) &&
3333 (st.st_mode & S_ISVTX);
3335 is_dir = de->d_type == DT_DIR;
3336 keep_around = false;
3342 /* if root_dev is set, remove subdirectories only, if device is same as dir */
3343 if (root_dev && st.st_dev != root_dev->st_dev)
3346 subdir_fd = openat(fd, de->d_name,
3347 O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3348 if (subdir_fd < 0) {
3349 if (ret == 0 && errno != ENOENT)
3354 r = rm_rf_children(subdir_fd, only_dirs, honour_sticky, root_dev);
3355 if (r < 0 && ret == 0)
3359 if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
3360 if (ret == 0 && errno != ENOENT)
3364 } else if (!only_dirs && !keep_around) {
3366 if (unlinkat(fd, de->d_name, 0) < 0) {
3367 if (ret == 0 && errno != ENOENT)
3378 int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
3383 if (fstatfs(fd, &s) < 0) {
3384 close_nointr_nofail(fd);
3388 /* We refuse to clean disk file systems with this call. This
3389 * is extra paranoia just to be sure we never ever remove
3392 if (s.f_type != TMPFS_MAGIC &&
3393 s.f_type != RAMFS_MAGIC) {
3394 log_error("Attempted to remove disk file system, and we can't allow that.");
3395 close_nointr_nofail(fd);
3399 return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev);
3402 static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
3408 /* We refuse to clean the root file system with this
3409 * call. This is extra paranoia to never cause a really
3410 * seriously broken system. */
3411 if (path_equal(path, "/")) {
3412 log_error("Attempted to remove entire root file system, and we can't allow that.");
3416 fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3419 if (errno != ENOTDIR)
3423 if (statfs(path, &s) < 0)
3426 if (s.f_type != TMPFS_MAGIC &&
3427 s.f_type != RAMFS_MAGIC) {
3428 log_error("Attempted to remove disk file system, and we can't allow that.");
3433 if (delete_root && !only_dirs)
3434 if (unlink(path) < 0 && errno != ENOENT)
3441 if (fstatfs(fd, &s) < 0) {
3442 close_nointr_nofail(fd);
3446 if (s.f_type != TMPFS_MAGIC &&
3447 s.f_type != RAMFS_MAGIC) {
3448 log_error("Attempted to remove disk file system, and we can't allow that.");
3449 close_nointr_nofail(fd);
3454 r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL);
3457 if (honour_sticky && file_is_priv_sticky(path) > 0)
3460 if (rmdir(path) < 0 && errno != ENOENT) {
3469 int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3470 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false);
3473 int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3474 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, true);
3477 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
3480 /* Under the assumption that we are running privileged we
3481 * first change the access mode and only then hand out
3482 * ownership to avoid a window where access is too open. */
3484 if (mode != (mode_t) -1)
3485 if (chmod(path, mode) < 0)
3488 if (uid != (uid_t) -1 || gid != (gid_t) -1)
3489 if (chown(path, uid, gid) < 0)
3495 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
3498 /* Under the assumption that we are running privileged we
3499 * first change the access mode and only then hand out
3500 * ownership to avoid a window where access is too open. */
3502 if (fchmod(fd, mode) < 0)
3505 if (fchown(fd, uid, gid) < 0)
3511 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
3515 /* Allocates the cpuset in the right size */
3518 if (!(r = CPU_ALLOC(n)))
3521 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
3522 CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
3532 if (errno != EINVAL)
3539 void status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) {
3541 static const char status_indent[] = " "; /* "[" STATUS "] " */
3543 struct iovec iovec[5];
3548 /* This is independent of logging, as status messages are
3549 * optional and go exclusively to the console. */
3551 if (vasprintf(&s, format, ap) < 0)
3554 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
3567 sl = status ? strlen(status_indent) : 0;
3573 e = ellipsize(s, emax, 75);
3583 if (!isempty(status)) {
3584 IOVEC_SET_STRING(iovec[n++], "[");
3585 IOVEC_SET_STRING(iovec[n++], status);
3586 IOVEC_SET_STRING(iovec[n++], "] ");
3588 IOVEC_SET_STRING(iovec[n++], status_indent);
3591 IOVEC_SET_STRING(iovec[n++], s);
3592 IOVEC_SET_STRING(iovec[n++], "\n");
3594 writev(fd, iovec, n);
3600 close_nointr_nofail(fd);
3603 void status_printf(const char *status, bool ellipse, const char *format, ...) {
3608 va_start(ap, format);
3609 status_vprintf(status, ellipse, format, ap);
3613 void status_welcome(void) {
3614 char *pretty_name = NULL, *ansi_color = NULL;
3615 const char *const_pretty = NULL, *const_color = NULL;
3618 if ((r = parse_env_file("/etc/os-release", NEWLINE,
3619 "PRETTY_NAME", &pretty_name,
3620 "ANSI_COLOR", &ansi_color,
3624 log_warning("Failed to read /etc/os-release: %s", strerror(-r));
3627 if (!pretty_name && !const_pretty)
3628 const_pretty = "Linux";
3630 if (!ansi_color && !const_color)
3635 "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
3636 const_color ? const_color : ansi_color,
3637 const_pretty ? const_pretty : pretty_name);
3643 char *replace_env(const char *format, char **env) {
3650 const char *e, *word = format;
3655 for (e = format; *e; e ++) {
3666 if (!(k = strnappend(r, word, e-word-1)))
3675 } else if (*e == '$') {
3676 if (!(k = strnappend(r, word, e-word)))
3692 if (!(t = strv_env_get_with_length(env, word+2, e-word-2)))
3695 if (!(k = strappend(r, t)))
3708 if (!(k = strnappend(r, word, e-word)))
3719 char **replace_env_argv(char **argv, char **env) {
3721 unsigned k = 0, l = 0;
3723 l = strv_length(argv);
3725 if (!(r = new(char*, l+1)))
3728 STRV_FOREACH(i, argv) {
3730 /* If $FOO appears as single word, replace it by the split up variable */
3731 if ((*i)[0] == '$' && (*i)[1] != '{') {
3736 if ((e = strv_env_get(env, *i+1))) {
3738 if (!(m = strv_split_quoted(e))) {
3749 if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
3758 memcpy(r + k, m, q * sizeof(char*));
3766 /* If ${FOO} appears as part of a word, replace it by the variable as-is */
3767 if (!(r[k++] = replace_env(*i, env))) {
3777 int fd_columns(int fd) {
3781 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3790 static unsigned columns_cached(bool cached) {
3791 static __thread int parsed_columns = 0, env_columns = -1;
3794 if (_likely_(parsed_columns > 0 && cached))
3795 return parsed_columns;
3797 if (_unlikely_(env_columns == -1)) {
3798 e = getenv("COLUMNS");
3800 env_columns = atoi(e);
3805 if (env_columns > 0) {
3806 parsed_columns = env_columns;
3807 return parsed_columns;
3810 if (parsed_columns <= 0 || !cached)
3811 parsed_columns = fd_columns(STDOUT_FILENO);
3813 if (parsed_columns <= 0)
3814 parsed_columns = 80;
3816 return parsed_columns;
3819 unsigned columns(void) {
3820 return columns_cached(true);
3823 unsigned columns_uncached(void) {
3824 return columns_cached(false);
3827 int fd_lines(int fd) {
3831 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3840 unsigned lines(void) {
3841 static __thread int parsed_lines = 0;
3844 if (_likely_(parsed_lines > 0))
3845 return parsed_lines;
3847 e = getenv("LINES");
3849 parsed_lines = atoi(e);
3851 if (parsed_lines <= 0)
3852 parsed_lines = fd_lines(STDOUT_FILENO);
3854 if (parsed_lines <= 0)
3857 return parsed_lines;
3860 int running_in_chroot(void) {
3866 /* Only works as root */
3868 if (stat("/proc/1/root", &a) < 0)
3871 if (stat("/", &b) < 0)
3875 a.st_dev != b.st_dev ||
3876 a.st_ino != b.st_ino;
3879 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
3884 assert(percent <= 100);
3885 assert(new_length >= 3);
3887 if (old_length <= 3 || old_length <= new_length)
3888 return strndup(s, old_length);
3890 r = new0(char, new_length+1);
3894 x = (new_length * percent) / 100;
3896 if (x > new_length - 3)
3904 s + old_length - (new_length - x - 3),
3905 new_length - x - 3);
3910 char *ellipsize(const char *s, size_t length, unsigned percent) {
3911 return ellipsize_mem(s, strlen(s), length, percent);
3914 int touch(const char *path) {
3919 if ((fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644)) < 0)
3922 close_nointr_nofail(fd);
3926 char *unquote(const char *s, const char* quotes) {
3934 if (strchr(quotes, s[0]) && s[l-1] == s[0])
3935 return strndup(s+1, l-2);
3940 char *normalize_env_assignment(const char *s) {
3941 char *name, *value, *p, *r;
3946 if (!(r = strdup(s)))
3952 if (!(name = strndup(s, p - s)))
3955 if (!(p = strdup(p+1))) {
3960 value = unquote(strstrip(p), QUOTES);
3968 if (asprintf(&r, "%s=%s", name, value) < 0)
3977 int wait_for_terminate(pid_t pid, siginfo_t *status) {
3988 if (waitid(P_PID, pid, status, WEXITED) < 0) {
4000 int wait_for_terminate_and_warn(const char *name, pid_t pid) {
4007 if ((r = wait_for_terminate(pid, &status)) < 0) {
4008 log_warning("Failed to wait for %s: %s", name, strerror(-r));
4012 if (status.si_code == CLD_EXITED) {
4013 if (status.si_status != 0) {
4014 log_warning("%s failed with error code %i.", name, status.si_status);
4015 return status.si_status;
4018 log_debug("%s succeeded.", name);
4021 } else if (status.si_code == CLD_KILLED ||
4022 status.si_code == CLD_DUMPED) {
4024 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
4028 log_warning("%s failed due to unknown reason.", name);
4033 _noreturn_ void freeze(void) {
4035 /* Make sure nobody waits for us on a socket anymore */
4036 close_all_fds(NULL, 0);
4044 bool null_or_empty(struct stat *st) {
4047 if (S_ISREG(st->st_mode) && st->st_size <= 0)
4050 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
4056 int null_or_empty_path(const char *fn) {
4061 if (stat(fn, &st) < 0)
4064 return null_or_empty(&st);
4067 DIR *xopendirat(int fd, const char *name, int flags) {
4071 if ((nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags)) < 0)
4074 if (!(d = fdopendir(nfd))) {
4075 close_nointr_nofail(nfd);
4082 int signal_from_string_try_harder(const char *s) {
4086 if ((signo = signal_from_string(s)) <= 0)
4087 if (startswith(s, "SIG"))
4088 return signal_from_string(s+3);
4093 void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) {
4099 if (!dual_timestamp_is_set(t))
4102 fprintf(f, "%s=%llu %llu\n",
4104 (unsigned long long) t->realtime,
4105 (unsigned long long) t->monotonic);
4108 void dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
4109 unsigned long long a, b;
4114 if (sscanf(value, "%lli %llu", &a, &b) != 2)
4115 log_debug("Failed to parse finish timestamp value %s", value);
4122 char *fstab_node_to_udev_node(const char *p) {
4126 /* FIXME: to follow udev's logic 100% we need to leave valid
4127 * UTF8 chars unescaped */
4129 if (startswith(p, "LABEL=")) {
4131 if (!(u = unquote(p+6, "\"\'")))
4134 t = xescape(u, "/ ");
4140 r = asprintf(&dn, "/dev/disk/by-label/%s", t);
4149 if (startswith(p, "UUID=")) {
4151 if (!(u = unquote(p+5, "\"\'")))
4154 t = xescape(u, "/ ");
4160 r = asprintf(&dn, "/dev/disk/by-uuid/%s", t);
4172 bool tty_is_vc(const char *tty) {
4175 if (startswith(tty, "/dev/"))
4178 return vtnr_from_tty(tty) >= 0;
4181 bool tty_is_console(const char *tty) {
4184 if (startswith(tty, "/dev/"))
4187 return streq(tty, "console");
4190 int vtnr_from_tty(const char *tty) {
4195 if (startswith(tty, "/dev/"))
4198 if (!startswith(tty, "tty") )
4201 if (tty[3] < '0' || tty[3] > '9')
4204 r = safe_atoi(tty+3, &i);
4208 if (i < 0 || i > 63)
4214 bool tty_is_vc_resolve(const char *tty) {
4215 char *active = NULL;
4220 if (startswith(tty, "/dev/"))
4223 /* Resolve where /dev/console is pointing to, if /sys is
4224 * actually ours (i.e. not read-only-mounted which is a sign
4225 * for container setups) */
4226 if (streq(tty, "console") && path_is_read_only_fs("/sys") <= 0)
4227 if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) {
4228 /* If multiple log outputs are configured the
4229 * last one is what /dev/console points to */
4230 tty = strrchr(active, ' ');
4243 const char *default_term_for_tty(const char *tty) {
4246 return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102";
4249 bool dirent_is_file(const struct dirent *de) {
4252 if (ignore_file(de->d_name))
4255 if (de->d_type != DT_REG &&
4256 de->d_type != DT_LNK &&
4257 de->d_type != DT_UNKNOWN)
4263 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
4266 if (!dirent_is_file(de))
4269 return endswith(de->d_name, suffix);
4272 void execute_directory(const char *directory, DIR *d, char *argv[]) {
4275 Hashmap *pids = NULL;
4279 /* Executes all binaries in a directory in parallel and waits
4280 * until all they all finished. */
4283 if (!(_d = opendir(directory))) {
4285 if (errno == ENOENT)
4288 log_error("Failed to enumerate directory %s: %m", directory);
4295 if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) {
4296 log_error("Failed to allocate set.");
4300 while ((de = readdir(d))) {
4305 if (!dirent_is_file(de))
4308 if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
4313 if ((pid = fork()) < 0) {
4314 log_error("Failed to fork: %m");
4332 log_error("Failed to execute %s: %m", path);
4333 _exit(EXIT_FAILURE);
4336 log_debug("Spawned %s as %lu", path, (unsigned long) pid);
4338 if ((k = hashmap_put(pids, UINT_TO_PTR(pid), path)) < 0) {
4339 log_error("Failed to add PID to set: %s", strerror(-k));
4344 while (!hashmap_isempty(pids)) {
4345 pid_t pid = PTR_TO_UINT(hashmap_first_key(pids));
4350 if (waitid(P_PID, pid, &si, WEXITED) < 0) {
4355 log_error("waitid() failed: %m");
4359 if ((path = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) {
4360 if (!is_clean_exit(si.si_code, si.si_status)) {
4361 if (si.si_code == CLD_EXITED)
4362 log_error("%s exited with exit status %i.", path, si.si_status);
4364 log_error("%s terminated by signal %s.", path, signal_to_string(si.si_status));
4366 log_debug("%s exited successfully.", path);
4377 hashmap_free_free(pids);
4380 int kill_and_sigcont(pid_t pid, int sig) {
4383 r = kill(pid, sig) < 0 ? -errno : 0;
4391 bool nulstr_contains(const char*nulstr, const char *needle) {
4397 NULSTR_FOREACH(i, nulstr)
4398 if (streq(i, needle))
4404 bool plymouth_running(void) {
4405 return access("/run/plymouth/pid", F_OK) >= 0;
4408 void parse_syslog_priority(char **p, int *priority) {
4409 int a = 0, b = 0, c = 0;
4419 if (!strchr(*p, '>'))
4422 if ((*p)[2] == '>') {
4423 c = undecchar((*p)[1]);
4425 } else if ((*p)[3] == '>') {
4426 b = undecchar((*p)[1]);
4427 c = undecchar((*p)[2]);
4429 } else if ((*p)[4] == '>') {
4430 a = undecchar((*p)[1]);
4431 b = undecchar((*p)[2]);
4432 c = undecchar((*p)[3]);
4437 if (a < 0 || b < 0 || c < 0)
4440 *priority = a*100+b*10+c;
4444 void skip_syslog_pid(char **buf) {
4456 p += strspn(p, "0123456789");
4466 void skip_syslog_date(char **buf) {
4474 LETTER, LETTER, LETTER,
4476 SPACE_OR_NUMBER, NUMBER,
4478 SPACE_OR_NUMBER, NUMBER,
4480 SPACE_OR_NUMBER, NUMBER,
4482 SPACE_OR_NUMBER, NUMBER,
4494 for (i = 0; i < ELEMENTSOF(sequence); i++, p++) {
4499 switch (sequence[i]) {
4506 case SPACE_OR_NUMBER:
4513 if (*p < '0' || *p > '9')
4519 if (!(*p >= 'A' && *p <= 'Z') &&
4520 !(*p >= 'a' && *p <= 'z'))
4536 char* strshorten(char *s, size_t l) {
4545 static bool hostname_valid_char(char c) {
4547 (c >= 'a' && c <= 'z') ||
4548 (c >= 'A' && c <= 'Z') ||
4549 (c >= '0' && c <= '9') ||
4555 bool hostname_is_valid(const char *s) {
4561 for (p = s; *p; p++)
4562 if (!hostname_valid_char(*p))
4565 if (p-s > HOST_NAME_MAX)
4571 char* hostname_cleanup(char *s) {
4574 for (p = s, d = s; *p; p++)
4575 if ((*p >= 'a' && *p <= 'z') ||
4576 (*p >= 'A' && *p <= 'Z') ||
4577 (*p >= '0' && *p <= '9') ||
4585 strshorten(s, HOST_NAME_MAX);
4589 int pipe_eof(int fd) {
4590 struct pollfd pollfd;
4595 pollfd.events = POLLIN|POLLHUP;
4597 r = poll(&pollfd, 1, 0);
4604 return pollfd.revents & POLLHUP;
4607 int fd_wait_for_event(int fd, int event, usec_t t) {
4608 struct pollfd pollfd;
4613 pollfd.events = event;
4615 r = poll(&pollfd, 1, t == (usec_t) -1 ? -1 : (int) (t / USEC_PER_MSEC));
4622 return pollfd.revents;
4625 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
4636 t = new(char, strlen(path) + 1 + 6 + 1);
4640 fn = path_get_file_name(path);
4644 stpcpy(stpcpy(t+k+1, fn), "XXXXXX");
4646 fd = mkostemp(t, O_WRONLY|O_CLOEXEC);
4652 f = fdopen(fd, "we");
4665 int terminal_vhangup_fd(int fd) {
4668 if (ioctl(fd, TIOCVHANGUP) < 0)
4674 int terminal_vhangup(const char *name) {
4677 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4681 r = terminal_vhangup_fd(fd);
4682 close_nointr_nofail(fd);
4687 int vt_disallocate(const char *name) {
4691 /* Deallocate the VT if possible. If not possible
4692 * (i.e. because it is the active one), at least clear it
4693 * entirely (including the scrollback buffer) */
4695 if (!startswith(name, "/dev/"))
4698 if (!tty_is_vc(name)) {
4699 /* So this is not a VT. I guess we cannot deallocate
4700 * it then. But let's at least clear the screen */
4702 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4707 "\033[r" /* clear scrolling region */
4708 "\033[H" /* move home */
4709 "\033[2J", /* clear screen */
4711 close_nointr_nofail(fd);
4716 if (!startswith(name, "/dev/tty"))
4719 r = safe_atou(name+8, &u);
4726 /* Try to deallocate */
4727 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
4731 r = ioctl(fd, VT_DISALLOCATE, u);
4732 close_nointr_nofail(fd);
4740 /* Couldn't deallocate, so let's clear it fully with
4742 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4747 "\033[r" /* clear scrolling region */
4748 "\033[H" /* move home */
4749 "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
4751 close_nointr_nofail(fd);
4756 int copy_file(const char *from, const char *to) {
4762 fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
4766 fdt = open(to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY, 0644);
4768 close_nointr_nofail(fdf);
4776 n = read(fdf, buf, sizeof(buf));
4780 close_nointr_nofail(fdf);
4791 k = loop_write(fdt, buf, n, false);
4793 r = k < 0 ? k : (errno ? -errno : -EIO);
4795 close_nointr_nofail(fdf);
4803 close_nointr_nofail(fdf);
4804 r = close_nointr(fdt);
4814 int symlink_or_copy(const char *from, const char *to) {
4815 char *pf = NULL, *pt = NULL;
4822 if (path_get_parent(from, &pf) < 0 ||
4823 path_get_parent(to, &pt) < 0) {
4828 if (stat(pf, &a) < 0 ||
4834 if (a.st_dev != b.st_dev) {
4838 return copy_file(from, to);
4841 if (symlink(from, to) < 0) {
4855 int symlink_or_copy_atomic(const char *from, const char *to) {
4859 unsigned long long ull;
4866 t = new(char, strlen(to) + 1 + 16 + 1);
4870 fn = path_get_file_name(to);
4874 x = stpcpy(t+k+1, fn);
4877 for (i = 0; i < 16; i++) {
4878 *(x++) = hexchar(ull & 0xF);
4884 r = symlink_or_copy(from, t);
4891 if (rename(t, to) < 0) {
4902 bool display_is_local(const char *display) {
4906 display[0] == ':' &&
4907 display[1] >= '0' &&
4911 int socket_from_display(const char *display, char **path) {
4918 if (!display_is_local(display))
4921 k = strspn(display+1, "0123456789");
4923 f = new(char, sizeof("/tmp/.X11-unix/X") + k);
4927 c = stpcpy(f, "/tmp/.X11-unix/X");
4928 memcpy(c, display+1, k);
4937 const char **username,
4938 uid_t *uid, gid_t *gid,
4940 const char **shell) {
4948 /* We enforce some special rules for uid=0: in order to avoid
4949 * NSS lookups for root we hardcode its data. */
4951 if (streq(*username, "root") || streq(*username, "0")) {
4969 if (parse_uid(*username, &u) >= 0) {
4973 /* If there are multiple users with the same id, make
4974 * sure to leave $USER to the configured value instead
4975 * of the first occurrence in the database. However if
4976 * the uid was configured by a numeric uid, then let's
4977 * pick the real username from /etc/passwd. */
4979 *username = p->pw_name;
4982 p = getpwnam(*username);
4986 return errno != 0 ? -errno : -ESRCH;
4998 *shell = p->pw_shell;
5003 int get_group_creds(const char **groupname, gid_t *gid) {
5009 /* We enforce some special rules for gid=0: in order to avoid
5010 * NSS lookups for root we hardcode its data. */
5012 if (streq(*groupname, "root") || streq(*groupname, "0")) {
5013 *groupname = "root";
5021 if (parse_gid(*groupname, &id) >= 0) {
5026 *groupname = g->gr_name;
5029 g = getgrnam(*groupname);
5033 return errno != 0 ? -errno : -ESRCH;
5041 int in_group(const char *name) {
5043 int ngroups_max, r, i;
5045 r = get_group_creds(&name, &gid);
5049 if (getgid() == gid)
5052 if (getegid() == gid)
5055 ngroups_max = sysconf(_SC_NGROUPS_MAX);
5056 assert(ngroups_max > 0);
5058 gids = alloca(sizeof(gid_t) * ngroups_max);
5060 r = getgroups(ngroups_max, gids);
5064 for (i = 0; i < r; i++)
5071 int glob_exists(const char *path) {
5079 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
5081 if (k == GLOB_NOMATCH)
5083 else if (k == GLOB_NOSPACE)
5086 r = !strv_isempty(g.gl_pathv);
5088 r = errno ? -errno : -EIO;
5095 int dirent_ensure_type(DIR *d, struct dirent *de) {
5101 if (de->d_type != DT_UNKNOWN)
5104 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
5108 S_ISREG(st.st_mode) ? DT_REG :
5109 S_ISDIR(st.st_mode) ? DT_DIR :
5110 S_ISLNK(st.st_mode) ? DT_LNK :
5111 S_ISFIFO(st.st_mode) ? DT_FIFO :
5112 S_ISSOCK(st.st_mode) ? DT_SOCK :
5113 S_ISCHR(st.st_mode) ? DT_CHR :
5114 S_ISBLK(st.st_mode) ? DT_BLK :
5120 int in_search_path(const char *path, char **search) {
5124 r = path_get_parent(path, &parent);
5130 STRV_FOREACH(i, search) {
5131 if (path_equal(parent, *i)) {
5142 int get_files_in_directory(const char *path, char ***list) {
5150 /* Returns all files in a directory in *list, and the number
5151 * of files as return value. If list is NULL returns only the
5159 struct dirent buffer, *de;
5162 k = readdir_r(d, &buffer, &de);
5171 dirent_ensure_type(d, de);
5173 if (!dirent_is_file(de))
5177 if ((unsigned) r >= n) {
5181 t = realloc(l, sizeof(char*) * n);
5190 assert((unsigned) r < n);
5192 l[r] = strdup(de->d_name);
5216 char *strjoin(const char *x, ...) {
5229 t = va_arg(ap, const char *);
5252 t = va_arg(ap, const char *);
5266 bool is_main_thread(void) {
5267 static __thread int cached = 0;
5269 if (_unlikely_(cached == 0))
5270 cached = getpid() == gettid() ? 1 : -1;
5275 int block_get_whole_disk(dev_t d, dev_t *ret) {
5282 /* If it has a queue this is good enough for us */
5283 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
5286 r = access(p, F_OK);
5294 /* If it is a partition find the originating device */
5295 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
5298 r = access(p, F_OK);
5304 /* Get parent dev_t */
5305 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
5308 r = read_one_line_file(p, &s);
5314 r = sscanf(s, "%u:%u", &m, &n);
5320 /* Only return this if it is really good enough for us. */
5321 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
5324 r = access(p, F_OK);
5328 *ret = makedev(m, n);
5335 int file_is_priv_sticky(const char *p) {
5340 if (lstat(p, &st) < 0)
5344 (st.st_uid == 0 || st.st_uid == getuid()) &&
5345 (st.st_mode & S_ISVTX);
5348 static const char *const ioprio_class_table[] = {
5349 [IOPRIO_CLASS_NONE] = "none",
5350 [IOPRIO_CLASS_RT] = "realtime",
5351 [IOPRIO_CLASS_BE] = "best-effort",
5352 [IOPRIO_CLASS_IDLE] = "idle"
5355 DEFINE_STRING_TABLE_LOOKUP(ioprio_class, int);
5357 static const char *const sigchld_code_table[] = {
5358 [CLD_EXITED] = "exited",
5359 [CLD_KILLED] = "killed",
5360 [CLD_DUMPED] = "dumped",
5361 [CLD_TRAPPED] = "trapped",
5362 [CLD_STOPPED] = "stopped",
5363 [CLD_CONTINUED] = "continued",
5366 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
5368 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
5369 [LOG_FAC(LOG_KERN)] = "kern",
5370 [LOG_FAC(LOG_USER)] = "user",
5371 [LOG_FAC(LOG_MAIL)] = "mail",
5372 [LOG_FAC(LOG_DAEMON)] = "daemon",
5373 [LOG_FAC(LOG_AUTH)] = "auth",
5374 [LOG_FAC(LOG_SYSLOG)] = "syslog",
5375 [LOG_FAC(LOG_LPR)] = "lpr",
5376 [LOG_FAC(LOG_NEWS)] = "news",
5377 [LOG_FAC(LOG_UUCP)] = "uucp",
5378 [LOG_FAC(LOG_CRON)] = "cron",
5379 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
5380 [LOG_FAC(LOG_FTP)] = "ftp",
5381 [LOG_FAC(LOG_LOCAL0)] = "local0",
5382 [LOG_FAC(LOG_LOCAL1)] = "local1",
5383 [LOG_FAC(LOG_LOCAL2)] = "local2",
5384 [LOG_FAC(LOG_LOCAL3)] = "local3",
5385 [LOG_FAC(LOG_LOCAL4)] = "local4",
5386 [LOG_FAC(LOG_LOCAL5)] = "local5",
5387 [LOG_FAC(LOG_LOCAL6)] = "local6",
5388 [LOG_FAC(LOG_LOCAL7)] = "local7"
5391 DEFINE_STRING_TABLE_LOOKUP(log_facility_unshifted, int);
5393 static const char *const log_level_table[] = {
5394 [LOG_EMERG] = "emerg",
5395 [LOG_ALERT] = "alert",
5396 [LOG_CRIT] = "crit",
5398 [LOG_WARNING] = "warning",
5399 [LOG_NOTICE] = "notice",
5400 [LOG_INFO] = "info",
5401 [LOG_DEBUG] = "debug"
5404 DEFINE_STRING_TABLE_LOOKUP(log_level, int);
5406 static const char* const sched_policy_table[] = {
5407 [SCHED_OTHER] = "other",
5408 [SCHED_BATCH] = "batch",
5409 [SCHED_IDLE] = "idle",
5410 [SCHED_FIFO] = "fifo",
5414 DEFINE_STRING_TABLE_LOOKUP(sched_policy, int);
5416 static const char* const rlimit_table[] = {
5417 [RLIMIT_CPU] = "LimitCPU",
5418 [RLIMIT_FSIZE] = "LimitFSIZE",
5419 [RLIMIT_DATA] = "LimitDATA",
5420 [RLIMIT_STACK] = "LimitSTACK",
5421 [RLIMIT_CORE] = "LimitCORE",
5422 [RLIMIT_RSS] = "LimitRSS",
5423 [RLIMIT_NOFILE] = "LimitNOFILE",
5424 [RLIMIT_AS] = "LimitAS",
5425 [RLIMIT_NPROC] = "LimitNPROC",
5426 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
5427 [RLIMIT_LOCKS] = "LimitLOCKS",
5428 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
5429 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
5430 [RLIMIT_NICE] = "LimitNICE",
5431 [RLIMIT_RTPRIO] = "LimitRTPRIO",
5432 [RLIMIT_RTTIME] = "LimitRTTIME"
5435 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
5437 static const char* const ip_tos_table[] = {
5438 [IPTOS_LOWDELAY] = "low-delay",
5439 [IPTOS_THROUGHPUT] = "throughput",
5440 [IPTOS_RELIABILITY] = "reliability",
5441 [IPTOS_LOWCOST] = "low-cost",
5444 DEFINE_STRING_TABLE_LOOKUP(ip_tos, int);
5446 static const char *const __signal_table[] = {
5463 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
5474 [SIGVTALRM] = "VTALRM",
5476 [SIGWINCH] = "WINCH",
5482 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
5484 const char *signal_to_string(int signo) {
5485 static __thread char buf[12];
5488 name = __signal_to_string(signo);
5492 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
5493 snprintf(buf, sizeof(buf) - 1, "RTMIN+%d", signo - SIGRTMIN);
5495 snprintf(buf, sizeof(buf) - 1, "%d", signo);
5500 int signal_from_string(const char *s) {
5505 signo =__signal_from_string(s);
5509 if (startswith(s, "RTMIN+")) {
5513 if (safe_atou(s, &u) >= 0) {
5514 signo = (int) u + offset;
5515 if (signo > 0 && signo < _NSIG)
5521 bool kexec_loaded(void) {
5522 bool loaded = false;
5525 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
5533 int strdup_or_null(const char *a, char **b) {
5551 int prot_from_flags(int flags) {
5553 switch (flags & O_ACCMODE) {
5562 return PROT_READ|PROT_WRITE;
5569 char *format_bytes(char *buf, size_t l, off_t t) {
5572 static const struct {
5576 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5577 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5578 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
5579 { "G", 1024ULL*1024ULL*1024ULL },
5580 { "M", 1024ULL*1024ULL },
5584 for (i = 0; i < ELEMENTSOF(table); i++) {
5586 if (t >= table[i].factor) {
5589 (unsigned long long) (t / table[i].factor),
5590 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
5597 snprintf(buf, l, "%lluB", (unsigned long long) t);
5605 void* memdup(const void *p, size_t l) {
5618 int fd_inc_sndbuf(int fd, size_t n) {
5620 socklen_t l = sizeof(value);
5622 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
5624 l == sizeof(value) &&
5625 (size_t) value >= n*2)
5629 r = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value));
5636 int fd_inc_rcvbuf(int fd, size_t n) {
5638 socklen_t l = sizeof(value);
5640 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
5642 l == sizeof(value) &&
5643 (size_t) value >= n*2)
5647 r = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value));
5654 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
5655 pid_t parent_pid, agent_pid;
5657 bool stdout_is_tty, stderr_is_tty;
5665 parent_pid = getpid();
5667 /* Spawns a temporary TTY agent, making sure it goes away when
5674 if (agent_pid != 0) {
5681 * Make sure the agent goes away when the parent dies */
5682 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
5683 _exit(EXIT_FAILURE);
5685 /* Check whether our parent died before we were able
5686 * to set the death signal */
5687 if (getppid() != parent_pid)
5688 _exit(EXIT_SUCCESS);
5690 /* Don't leak fds to the agent */
5691 close_all_fds(except, n_except);
5693 stdout_is_tty = isatty(STDOUT_FILENO);
5694 stderr_is_tty = isatty(STDERR_FILENO);
5696 if (!stdout_is_tty || !stderr_is_tty) {
5697 /* Detach from stdout/stderr. and reopen
5698 * /dev/tty for them. This is important to
5699 * ensure that when systemctl is started via
5700 * popen() or a similar call that expects to
5701 * read EOF we actually do generate EOF and
5702 * not delay this indefinitely by because we
5703 * keep an unused copy of stdin around. */
5704 fd = open("/dev/tty", O_WRONLY);
5706 log_error("Failed to open /dev/tty: %m");
5707 _exit(EXIT_FAILURE);
5711 dup2(fd, STDOUT_FILENO);
5714 dup2(fd, STDERR_FILENO);
5720 /* Count arguments */
5722 for (n = 0; va_arg(ap, char*); n++)
5727 l = alloca(sizeof(char *) * (n + 1));
5729 /* Fill in arguments */
5731 for (i = 0; i <= n; i++)
5732 l[i] = va_arg(ap, char*);
5736 _exit(EXIT_FAILURE);
5739 int setrlimit_closest(int resource, const struct rlimit *rlim) {
5740 struct rlimit highest, fixed;
5744 if (setrlimit(resource, rlim) >= 0)
5750 /* So we failed to set the desired setrlimit, then let's try
5751 * to get as close as we can */
5752 assert_se(getrlimit(resource, &highest) == 0);
5754 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
5755 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
5757 if (setrlimit(resource, &fixed) < 0)
5763 int getenv_for_pid(pid_t pid, const char *field, char **_value) {
5764 char path[sizeof("/proc/")-1+10+sizeof("/environ")], *value = NULL;
5776 snprintf(path, sizeof(path), "/proc/%lu/environ", (unsigned long) pid);
5779 f = fopen(path, "re");
5787 char line[LINE_MAX];
5790 for (i = 0; i < sizeof(line)-1; i++) {
5794 if (_unlikely_(c == EOF)) {
5804 if (memcmp(line, field, l) == 0 && line[l] == '=') {
5805 value = strdup(line + l + 1);
5825 int can_sleep(const char *type) {
5826 char *p, *w, *state;
5833 r = read_one_line_file("/sys/power/state", &p);
5835 return r == -ENOENT ? 0 : r;
5839 FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state) {
5840 if (l == k && strncmp(w, type, l) == 0) {
5850 bool is_valid_documentation_url(const char *url) {
5853 if (startswith(url, "http://") && url[7])
5856 if (startswith(url, "https://") && url[8])
5859 if (startswith(url, "file:") && url[5])
5862 if (startswith(url, "info:") && url[5])
5865 if (startswith(url, "man:") && url[4])
5871 bool in_initrd(void) {
5872 static int saved = -1;
5878 /* We make two checks here:
5880 * 1. the flag file /etc/initrd-release must exist
5881 * 2. the root file system must be a memory file system
5883 * The second check is extra paranoia, since misdetecting an
5884 * initrd can have bad bad consequences due the initrd
5885 * emptying when transititioning to the main systemd.
5888 saved = access("/etc/initrd-release", F_OK) >= 0 &&
5889 statfs("/", &s) >= 0 &&
5890 (s.f_type == TMPFS_MAGIC || s.f_type == RAMFS_MAGIC);
5895 void warn_melody(void) {
5898 fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
5902 /* Yeah, this is synchronous. Kinda sucks. Bute well... */
5904 ioctl(fd, KIOCSOUND, (int)(1193180/440));
5905 usleep(125*USEC_PER_MSEC);
5907 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5908 usleep(125*USEC_PER_MSEC);
5910 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5911 usleep(125*USEC_PER_MSEC);
5913 ioctl(fd, KIOCSOUND, 0);
5914 close_nointr_nofail(fd);
5917 int make_console_stdio(void) {
5920 /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
5922 fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1);
5924 log_error("Failed to acquire terminal: %s", strerror(-fd));
5930 log_error("Failed to duplicate terminal fd: %s", strerror(-r));
5937 int get_home_dir(char **_h) {
5945 /* Take the user specified one */
5956 /* Hardcode home directory for root to avoid NSS */
5959 h = strdup("/root");
5967 /* Check the database... */
5971 return errno ? -errno : -ENOENT;
5973 if (!path_is_absolute(p->pw_dir))
5976 h = strdup(p->pw_dir);
5984 int get_shell(char **_sh) {
5992 /* Take the user specified one */
5993 e = getenv("SHELL");
6003 /* Hardcode home directory for root to avoid NSS */
6006 sh = strdup("/bin/sh");
6014 /* Check the database... */
6018 return errno ? -errno : -ESRCH;
6020 if (!path_is_absolute(p->pw_shell))
6023 sh = strdup(p->pw_shell);