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 static bool ignore_file_allow_backup(const char *filename) {
1807 filename[0] == '.' ||
1808 streq(filename, "lost+found") ||
1809 streq(filename, "aquota.user") ||
1810 streq(filename, "aquota.group") ||
1811 endswith(filename, ".rpmnew") ||
1812 endswith(filename, ".rpmsave") ||
1813 endswith(filename, ".rpmorig") ||
1814 endswith(filename, ".dpkg-old") ||
1815 endswith(filename, ".dpkg-new") ||
1816 endswith(filename, ".swp");
1819 bool ignore_file(const char *filename) {
1822 if (endswith(filename, "~"))
1825 return ignore_file_allow_backup(filename);
1828 int fd_nonblock(int fd, bool nonblock) {
1833 if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
1837 flags |= O_NONBLOCK;
1839 flags &= ~O_NONBLOCK;
1841 if (fcntl(fd, F_SETFL, flags) < 0)
1847 int fd_cloexec(int fd, bool cloexec) {
1852 if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
1856 flags |= FD_CLOEXEC;
1858 flags &= ~FD_CLOEXEC;
1860 if (fcntl(fd, F_SETFD, flags) < 0)
1866 static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
1869 assert(n_fdset == 0 || fdset);
1871 for (i = 0; i < n_fdset; i++)
1878 int close_all_fds(const int except[], unsigned n_except) {
1883 assert(n_except == 0 || except);
1885 d = opendir("/proc/self/fd");
1890 /* When /proc isn't available (for example in chroots)
1891 * the fallback is brute forcing through the fd
1894 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
1895 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
1897 if (fd_in_set(fd, except, n_except))
1900 if (close_nointr(fd) < 0)
1901 if (errno != EBADF && r == 0)
1908 while ((de = readdir(d))) {
1911 if (ignore_file(de->d_name))
1914 if (safe_atoi(de->d_name, &fd) < 0)
1915 /* Let's better ignore this, just in case */
1924 if (fd_in_set(fd, except, n_except))
1927 if (close_nointr(fd) < 0) {
1928 /* Valgrind has its own FD and doesn't want to have it closed */
1929 if (errno != EBADF && r == 0)
1938 bool chars_intersect(const char *a, const char *b) {
1941 /* Returns true if any of the chars in a are in b. */
1942 for (p = a; *p; p++)
1949 char *format_timestamp(char *buf, size_t l, usec_t t) {
1959 sec = (time_t) (t / USEC_PER_SEC);
1961 if (strftime(buf, l, "%a, %d %b %Y %H:%M:%S %z", localtime_r(&sec, &tm)) <= 0)
1967 char *format_timestamp_pretty(char *buf, size_t l, usec_t t) {
1970 n = now(CLOCK_REALTIME);
1972 if (t <= 0 || t > n || t + USEC_PER_DAY*7 <= t)
1977 if (d >= USEC_PER_YEAR)
1978 snprintf(buf, l, "%llu years and %llu months ago",
1979 (unsigned long long) (d / USEC_PER_YEAR),
1980 (unsigned long long) ((d % USEC_PER_YEAR) / USEC_PER_MONTH));
1981 else if (d >= USEC_PER_MONTH)
1982 snprintf(buf, l, "%llu months and %llu days ago",
1983 (unsigned long long) (d / USEC_PER_MONTH),
1984 (unsigned long long) ((d % USEC_PER_MONTH) / USEC_PER_DAY));
1985 else if (d >= USEC_PER_WEEK)
1986 snprintf(buf, l, "%llu weeks and %llu days ago",
1987 (unsigned long long) (d / USEC_PER_WEEK),
1988 (unsigned long long) ((d % USEC_PER_WEEK) / USEC_PER_DAY));
1989 else if (d >= 2*USEC_PER_DAY)
1990 snprintf(buf, l, "%llu days ago", (unsigned long long) (d / USEC_PER_DAY));
1991 else if (d >= 25*USEC_PER_HOUR)
1992 snprintf(buf, l, "1 day and %lluh ago",
1993 (unsigned long long) ((d - USEC_PER_DAY) / USEC_PER_HOUR));
1994 else if (d >= 6*USEC_PER_HOUR)
1995 snprintf(buf, l, "%lluh ago",
1996 (unsigned long long) (d / USEC_PER_HOUR));
1997 else if (d >= USEC_PER_HOUR)
1998 snprintf(buf, l, "%lluh %llumin ago",
1999 (unsigned long long) (d / USEC_PER_HOUR),
2000 (unsigned long long) ((d % USEC_PER_HOUR) / USEC_PER_MINUTE));
2001 else if (d >= 5*USEC_PER_MINUTE)
2002 snprintf(buf, l, "%llumin ago",
2003 (unsigned long long) (d / USEC_PER_MINUTE));
2004 else if (d >= USEC_PER_MINUTE)
2005 snprintf(buf, l, "%llumin %llus ago",
2006 (unsigned long long) (d / USEC_PER_MINUTE),
2007 (unsigned long long) ((d % USEC_PER_MINUTE) / USEC_PER_SEC));
2008 else if (d >= USEC_PER_SEC)
2009 snprintf(buf, l, "%llus ago",
2010 (unsigned long long) (d / USEC_PER_SEC));
2011 else if (d >= USEC_PER_MSEC)
2012 snprintf(buf, l, "%llums ago",
2013 (unsigned long long) (d / USEC_PER_MSEC));
2015 snprintf(buf, l, "%lluus ago",
2016 (unsigned long long) d);
2018 snprintf(buf, l, "now");
2024 char *format_timespan(char *buf, size_t l, usec_t t) {
2025 static const struct {
2029 { "w", USEC_PER_WEEK },
2030 { "d", USEC_PER_DAY },
2031 { "h", USEC_PER_HOUR },
2032 { "min", USEC_PER_MINUTE },
2033 { "s", USEC_PER_SEC },
2034 { "ms", USEC_PER_MSEC },
2044 if (t == (usec_t) -1)
2048 snprintf(p, l, "0");
2053 /* The result of this function can be parsed with parse_usec */
2055 for (i = 0; i < ELEMENTSOF(table); i++) {
2059 if (t < table[i].usec)
2065 k = snprintf(p, l, "%s%llu%s", p > buf ? " " : "", (unsigned long long) (t / table[i].usec), table[i].suffix);
2066 n = MIN((size_t) k, l);
2079 bool fstype_is_network(const char *fstype) {
2080 static const char * const table[] = {
2092 for (i = 0; i < ELEMENTSOF(table); i++)
2093 if (streq(table[i], fstype))
2102 if ((fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0)
2107 TIOCL_GETKMSGREDIRECT,
2111 if (ioctl(fd, TIOCLINUX, tiocl) < 0) {
2116 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
2119 if (ioctl(fd, VT_ACTIVATE, vt) < 0)
2123 close_nointr_nofail(fd);
2127 int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
2128 struct termios old_termios, new_termios;
2130 char line[LINE_MAX];
2135 if (tcgetattr(fileno(f), &old_termios) >= 0) {
2136 new_termios = old_termios;
2138 new_termios.c_lflag &= ~ICANON;
2139 new_termios.c_cc[VMIN] = 1;
2140 new_termios.c_cc[VTIME] = 0;
2142 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
2145 if (t != (usec_t) -1) {
2146 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
2147 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
2152 k = fread(&c, 1, 1, f);
2154 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
2160 *need_nl = c != '\n';
2167 if (t != (usec_t) -1)
2168 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
2171 if (!fgets(line, sizeof(line), f))
2176 if (strlen(line) != 1)
2186 int ask(char *ret, const char *replies, const char *text, ...) {
2193 on_tty = isatty(STDOUT_FILENO);
2199 bool need_nl = true;
2202 fputs(ANSI_HIGHLIGHT_ON, stdout);
2209 fputs(ANSI_HIGHLIGHT_OFF, stdout);
2213 r = read_one_char(stdin, &c, (usec_t) -1, &need_nl);
2216 if (r == -EBADMSG) {
2217 puts("Bad input, please try again.");
2228 if (strchr(replies, c)) {
2233 puts("Read unexpected character, please try again.");
2237 int reset_terminal_fd(int fd, bool switch_to_text) {
2238 struct termios termios;
2241 /* Set terminal to some sane defaults */
2245 /* We leave locked terminal attributes untouched, so that
2246 * Plymouth may set whatever it wants to set, and we don't
2247 * interfere with that. */
2249 /* Disable exclusive mode, just in case */
2250 ioctl(fd, TIOCNXCL);
2252 /* Switch to text mode */
2254 ioctl(fd, KDSETMODE, KD_TEXT);
2256 /* Enable console unicode mode */
2257 ioctl(fd, KDSKBMODE, K_UNICODE);
2259 if (tcgetattr(fd, &termios) < 0) {
2264 /* We only reset the stuff that matters to the software. How
2265 * hardware is set up we don't touch assuming that somebody
2266 * else will do that for us */
2268 termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
2269 termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
2270 termios.c_oflag |= ONLCR;
2271 termios.c_cflag |= CREAD;
2272 termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
2274 termios.c_cc[VINTR] = 03; /* ^C */
2275 termios.c_cc[VQUIT] = 034; /* ^\ */
2276 termios.c_cc[VERASE] = 0177;
2277 termios.c_cc[VKILL] = 025; /* ^X */
2278 termios.c_cc[VEOF] = 04; /* ^D */
2279 termios.c_cc[VSTART] = 021; /* ^Q */
2280 termios.c_cc[VSTOP] = 023; /* ^S */
2281 termios.c_cc[VSUSP] = 032; /* ^Z */
2282 termios.c_cc[VLNEXT] = 026; /* ^V */
2283 termios.c_cc[VWERASE] = 027; /* ^W */
2284 termios.c_cc[VREPRINT] = 022; /* ^R */
2285 termios.c_cc[VEOL] = 0;
2286 termios.c_cc[VEOL2] = 0;
2288 termios.c_cc[VTIME] = 0;
2289 termios.c_cc[VMIN] = 1;
2291 if (tcsetattr(fd, TCSANOW, &termios) < 0)
2295 /* Just in case, flush all crap out */
2296 tcflush(fd, TCIOFLUSH);
2301 int reset_terminal(const char *name) {
2304 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2308 r = reset_terminal_fd(fd, true);
2309 close_nointr_nofail(fd);
2314 int open_terminal(const char *name, int mode) {
2319 * If a TTY is in the process of being closed opening it might
2320 * cause EIO. This is horribly awful, but unlikely to be
2321 * changed in the kernel. Hence we work around this problem by
2322 * retrying a couple of times.
2324 * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
2328 fd = open(name, mode);
2335 /* Max 1s in total */
2339 usleep(50 * USEC_PER_MSEC);
2348 close_nointr_nofail(fd);
2353 close_nointr_nofail(fd);
2360 int flush_fd(int fd) {
2361 struct pollfd pollfd;
2365 pollfd.events = POLLIN;
2372 if ((r = poll(&pollfd, 1, 0)) < 0) {
2383 if ((l = read(fd, buf, sizeof(buf))) < 0) {
2388 if (errno == EAGAIN)
2399 int acquire_terminal(
2403 bool ignore_tiocstty_eperm,
2406 int fd = -1, notify = -1, r = 0, wd = -1;
2408 struct sigaction sa_old, sa_new;
2412 /* We use inotify to be notified when the tty is closed. We
2413 * create the watch before checking if we can actually acquire
2414 * it, so that we don't lose any event.
2416 * Note: strictly speaking this actually watches for the
2417 * device being closed, it does *not* really watch whether a
2418 * tty loses its controlling process. However, unless some
2419 * rogue process uses TIOCNOTTY on /dev/tty *after* closing
2420 * its tty otherwise this will not become a problem. As long
2421 * as the administrator makes sure not configure any service
2422 * on the same tty as an untrusted user this should not be a
2423 * problem. (Which he probably should not do anyway.) */
2425 if (timeout != (usec_t) -1)
2426 ts = now(CLOCK_MONOTONIC);
2428 if (!fail && !force) {
2429 notify = inotify_init1(IN_CLOEXEC | (timeout != (usec_t) -1 ? IN_NONBLOCK : 0));
2435 wd = inotify_add_watch(notify, name, IN_CLOSE);
2444 r = flush_fd(notify);
2449 /* We pass here O_NOCTTY only so that we can check the return
2450 * value TIOCSCTTY and have a reliable way to figure out if we
2451 * successfully became the controlling process of the tty */
2452 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2456 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2457 * if we already own the tty. */
2459 sa_new.sa_handler = SIG_IGN;
2460 sa_new.sa_flags = SA_RESTART;
2461 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2463 /* First, try to get the tty */
2464 if (ioctl(fd, TIOCSCTTY, force) < 0)
2467 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2469 /* Sometimes it makes sense to ignore TIOCSCTTY
2470 * returning EPERM, i.e. when very likely we already
2471 * are have this controlling terminal. */
2472 if (r < 0 && r == -EPERM && ignore_tiocstty_eperm)
2475 if (r < 0 && (force || fail || r != -EPERM)) {
2484 assert(notify >= 0);
2487 uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
2489 struct inotify_event *e;
2491 if (timeout != (usec_t) -1) {
2494 n = now(CLOCK_MONOTONIC);
2495 if (ts + timeout < n) {
2500 r = fd_wait_for_event(fd, POLLIN, ts + timeout - n);
2510 l = read(notify, inotify_buffer, sizeof(inotify_buffer));
2513 if (errno == EINTR || errno == EAGAIN)
2520 e = (struct inotify_event*) inotify_buffer;
2525 if (e->wd != wd || !(e->mask & IN_CLOSE)) {
2530 step = sizeof(struct inotify_event) + e->len;
2531 assert(step <= (size_t) l);
2533 e = (struct inotify_event*) ((uint8_t*) e + step);
2540 /* We close the tty fd here since if the old session
2541 * ended our handle will be dead. It's important that
2542 * we do this after sleeping, so that we don't enter
2543 * an endless loop. */
2544 close_nointr_nofail(fd);
2548 close_nointr_nofail(notify);
2550 r = reset_terminal_fd(fd, true);
2552 log_warning("Failed to reset terminal: %s", strerror(-r));
2558 close_nointr_nofail(fd);
2561 close_nointr_nofail(notify);
2566 int release_terminal(void) {
2568 struct sigaction sa_old, sa_new;
2570 if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC)) < 0)
2573 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2574 * by our own TIOCNOTTY */
2577 sa_new.sa_handler = SIG_IGN;
2578 sa_new.sa_flags = SA_RESTART;
2579 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2581 if (ioctl(fd, TIOCNOTTY) < 0)
2584 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2586 close_nointr_nofail(fd);
2590 int sigaction_many(const struct sigaction *sa, ...) {
2595 while ((sig = va_arg(ap, int)) > 0)
2596 if (sigaction(sig, sa, NULL) < 0)
2603 int ignore_signals(int sig, ...) {
2604 struct sigaction sa;
2609 sa.sa_handler = SIG_IGN;
2610 sa.sa_flags = SA_RESTART;
2612 if (sigaction(sig, &sa, NULL) < 0)
2616 while ((sig = va_arg(ap, int)) > 0)
2617 if (sigaction(sig, &sa, NULL) < 0)
2624 int default_signals(int sig, ...) {
2625 struct sigaction sa;
2630 sa.sa_handler = SIG_DFL;
2631 sa.sa_flags = SA_RESTART;
2633 if (sigaction(sig, &sa, NULL) < 0)
2637 while ((sig = va_arg(ap, int)) > 0)
2638 if (sigaction(sig, &sa, NULL) < 0)
2645 int close_pipe(int p[]) {
2651 a = close_nointr(p[0]);
2656 b = close_nointr(p[1]);
2660 return a < 0 ? a : b;
2663 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2672 while (nbytes > 0) {
2675 if ((k = read(fd, p, nbytes)) <= 0) {
2677 if (k < 0 && errno == EINTR)
2680 if (k < 0 && errno == EAGAIN && do_poll) {
2681 struct pollfd pollfd;
2685 pollfd.events = POLLIN;
2687 if (poll(&pollfd, 1, -1) < 0) {
2691 return n > 0 ? n : -errno;
2694 if (pollfd.revents != POLLIN)
2695 return n > 0 ? n : -EIO;
2700 return n > 0 ? n : (k < 0 ? -errno : 0);
2711 ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2720 while (nbytes > 0) {
2723 k = write(fd, p, nbytes);
2726 if (k < 0 && errno == EINTR)
2729 if (k < 0 && errno == EAGAIN && do_poll) {
2730 struct pollfd pollfd;
2734 pollfd.events = POLLOUT;
2736 if (poll(&pollfd, 1, -1) < 0) {
2740 return n > 0 ? n : -errno;
2743 if (pollfd.revents != POLLOUT)
2744 return n > 0 ? n : -EIO;
2749 return n > 0 ? n : (k < 0 ? -errno : 0);
2760 int parse_usec(const char *t, usec_t *usec) {
2761 static const struct {
2765 { "sec", USEC_PER_SEC },
2766 { "s", USEC_PER_SEC },
2767 { "min", USEC_PER_MINUTE },
2768 { "hr", USEC_PER_HOUR },
2769 { "h", USEC_PER_HOUR },
2770 { "d", USEC_PER_DAY },
2771 { "w", USEC_PER_WEEK },
2772 { "msec", USEC_PER_MSEC },
2773 { "ms", USEC_PER_MSEC },
2774 { "m", USEC_PER_MINUTE },
2777 { "", USEC_PER_SEC }, /* default is sec */
2793 l = strtoll(p, &e, 10);
2804 e += strspn(e, WHITESPACE);
2806 for (i = 0; i < ELEMENTSOF(table); i++)
2807 if (startswith(e, table[i].suffix)) {
2808 r += (usec_t) l * table[i].usec;
2809 p = e + strlen(table[i].suffix);
2813 if (i >= ELEMENTSOF(table))
2823 int parse_nsec(const char *t, nsec_t *nsec) {
2824 static const struct {
2828 { "sec", NSEC_PER_SEC },
2829 { "s", NSEC_PER_SEC },
2830 { "min", NSEC_PER_MINUTE },
2831 { "hr", NSEC_PER_HOUR },
2832 { "h", NSEC_PER_HOUR },
2833 { "d", NSEC_PER_DAY },
2834 { "w", NSEC_PER_WEEK },
2835 { "msec", NSEC_PER_MSEC },
2836 { "ms", NSEC_PER_MSEC },
2837 { "m", NSEC_PER_MINUTE },
2838 { "usec", NSEC_PER_USEC },
2839 { "us", NSEC_PER_USEC },
2842 { "", 1ULL }, /* default is nsec */
2858 l = strtoll(p, &e, 10);
2869 e += strspn(e, WHITESPACE);
2871 for (i = 0; i < ELEMENTSOF(table); i++)
2872 if (startswith(e, table[i].suffix)) {
2873 r += (nsec_t) l * table[i].nsec;
2874 p = e + strlen(table[i].suffix);
2878 if (i >= ELEMENTSOF(table))
2888 int parse_bytes(const char *t, off_t *bytes) {
2889 static const struct {
2895 { "M", 1024ULL*1024ULL },
2896 { "G", 1024ULL*1024ULL*1024ULL },
2897 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2898 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2899 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2916 l = strtoll(p, &e, 10);
2927 e += strspn(e, WHITESPACE);
2929 for (i = 0; i < ELEMENTSOF(table); i++)
2930 if (startswith(e, table[i].suffix)) {
2931 r += (off_t) l * table[i].factor;
2932 p = e + strlen(table[i].suffix);
2936 if (i >= ELEMENTSOF(table))
2946 int make_stdio(int fd) {
2951 r = dup2(fd, STDIN_FILENO);
2952 s = dup2(fd, STDOUT_FILENO);
2953 t = dup2(fd, STDERR_FILENO);
2956 close_nointr_nofail(fd);
2958 if (r < 0 || s < 0 || t < 0)
2961 fd_cloexec(STDIN_FILENO, false);
2962 fd_cloexec(STDOUT_FILENO, false);
2963 fd_cloexec(STDERR_FILENO, false);
2968 int make_null_stdio(void) {
2971 null_fd = open("/dev/null", O_RDWR|O_NOCTTY);
2975 return make_stdio(null_fd);
2978 bool is_device_path(const char *path) {
2980 /* Returns true on paths that refer to a device, either in
2981 * sysfs or in /dev */
2984 path_startswith(path, "/dev/") ||
2985 path_startswith(path, "/sys/");
2988 int dir_is_empty(const char *path) {
2991 struct dirent buf, *de;
2993 if (!(d = opendir(path)))
2997 if ((r = readdir_r(d, &buf, &de)) > 0) {
3007 if (!ignore_file(de->d_name)) {
3017 unsigned long long random_ull(void) {
3022 fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
3026 r = loop_read(fd, &ull, sizeof(ull), true);
3027 close_nointr_nofail(fd);
3029 if (r != sizeof(ull))
3035 return random() * RAND_MAX + random();
3038 void rename_process(const char name[8]) {
3041 /* This is a like a poor man's setproctitle(). It changes the
3042 * comm field, argv[0], and also the glibc's internally used
3043 * name of the process. For the first one a limit of 16 chars
3044 * applies, to the second one usually one of 10 (i.e. length
3045 * of "/sbin/init"), to the third one one of 7 (i.e. length of
3046 * "systemd"). If you pass a longer string it will be
3049 prctl(PR_SET_NAME, name);
3051 if (program_invocation_name)
3052 strncpy(program_invocation_name, name, strlen(program_invocation_name));
3054 if (saved_argc > 0) {
3058 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
3060 for (i = 1; i < saved_argc; i++) {
3064 memset(saved_argv[i], 0, strlen(saved_argv[i]));
3069 void sigset_add_many(sigset_t *ss, ...) {
3076 while ((sig = va_arg(ap, int)) > 0)
3077 assert_se(sigaddset(ss, sig) == 0);
3081 char* gethostname_malloc(void) {
3084 assert_se(uname(&u) >= 0);
3086 if (!isempty(u.nodename) && !streq(u.nodename, "(none)"))
3087 return strdup(u.nodename);
3089 return strdup(u.sysname);
3092 bool hostname_is_set(void) {
3095 assert_se(uname(&u) >= 0);
3097 return !isempty(u.nodename) && !streq(u.nodename, "(none)");
3100 static char *lookup_uid(uid_t uid) {
3103 struct passwd pwbuf, *pw = NULL;
3105 /* Shortcut things to avoid NSS lookups */
3107 return strdup("root");
3109 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
3113 buf = malloc(bufsize);
3117 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw) {
3118 name = strdup(pw->pw_name);
3125 if (asprintf(&name, "%lu", (unsigned long) uid) < 0)
3131 char* getlogname_malloc(void) {
3135 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
3140 return lookup_uid(uid);
3143 char *getusername_malloc(void) {
3150 return lookup_uid(getuid());
3153 int getttyname_malloc(int fd, char **r) {
3154 char path[PATH_MAX], *c;
3159 if ((k = ttyname_r(fd, path, sizeof(path))) != 0)
3164 if (!(c = strdup(startswith(path, "/dev/") ? path + 5 : path)))
3171 int getttyname_harder(int fd, char **r) {
3175 if ((k = getttyname_malloc(fd, &s)) < 0)
3178 if (streq(s, "tty")) {
3180 return get_ctty(0, NULL, r);
3187 int get_ctty_devnr(pid_t pid, dev_t *d) {
3189 char line[LINE_MAX], *p, *fn;
3190 unsigned long ttynr;
3193 if (asprintf(&fn, "/proc/%lu/stat", (unsigned long) (pid <= 0 ? getpid() : pid)) < 0)
3196 f = fopen(fn, "re");
3201 if (!fgets(line, sizeof(line), f)) {
3202 k = feof(f) ? -EIO : -errno;
3209 p = strrchr(line, ')');
3219 "%*d " /* session */
3228 int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
3230 char fn[PATH_MAX], *s, *b, *p;
3235 k = get_ctty_devnr(pid, &devnr);
3239 snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
3242 if ((k = readlink_malloc(fn, &s)) < 0) {
3247 /* This is an ugly hack */
3248 if (major(devnr) == 136) {
3249 if (asprintf(&b, "pts/%lu", (unsigned long) minor(devnr)) < 0)
3259 /* Probably something like the ptys which have no
3260 * symlink in /dev/char. Let's return something
3261 * vaguely useful. */
3263 if (!(b = strdup(fn + 5)))
3273 if (startswith(s, "/dev/"))
3275 else if (startswith(s, "../"))
3293 int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
3299 /* This returns the first error we run into, but nevertheless
3300 * tries to go on. This closes the passed fd. */
3304 close_nointr_nofail(fd);
3306 return errno == ENOENT ? 0 : -errno;
3310 struct dirent buf, *de;
3311 bool is_dir, keep_around;
3315 r = readdir_r(d, &buf, &de);
3316 if (r != 0 && ret == 0) {
3324 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
3327 if (de->d_type == DT_UNKNOWN ||
3329 (de->d_type == DT_DIR && root_dev)) {
3330 if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
3331 if (ret == 0 && errno != ENOENT)
3336 is_dir = S_ISDIR(st.st_mode);
3339 (st.st_uid == 0 || st.st_uid == getuid()) &&
3340 (st.st_mode & S_ISVTX);
3342 is_dir = de->d_type == DT_DIR;
3343 keep_around = false;
3349 /* if root_dev is set, remove subdirectories only, if device is same as dir */
3350 if (root_dev && st.st_dev != root_dev->st_dev)
3353 subdir_fd = openat(fd, de->d_name,
3354 O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3355 if (subdir_fd < 0) {
3356 if (ret == 0 && errno != ENOENT)
3361 r = rm_rf_children_dangerous(subdir_fd, only_dirs, honour_sticky, root_dev);
3362 if (r < 0 && ret == 0)
3366 if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
3367 if (ret == 0 && errno != ENOENT)
3371 } else if (!only_dirs && !keep_around) {
3373 if (unlinkat(fd, de->d_name, 0) < 0) {
3374 if (ret == 0 && errno != ENOENT)
3385 int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
3390 if (fstatfs(fd, &s) < 0) {
3391 close_nointr_nofail(fd);
3395 /* We refuse to clean disk file systems with this call. This
3396 * is extra paranoia just to be sure we never ever remove
3399 if (s.f_type != TMPFS_MAGIC &&
3400 s.f_type != RAMFS_MAGIC) {
3401 log_error("Attempted to remove disk file system, and we can't allow that.");
3402 close_nointr_nofail(fd);
3406 return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev);
3409 static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
3415 /* We refuse to clean the root file system with this
3416 * call. This is extra paranoia to never cause a really
3417 * seriously broken system. */
3418 if (path_equal(path, "/")) {
3419 log_error("Attempted to remove entire root file system, and we can't allow that.");
3423 fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3426 if (errno != ENOTDIR)
3430 if (statfs(path, &s) < 0)
3433 if (s.f_type != TMPFS_MAGIC &&
3434 s.f_type != RAMFS_MAGIC) {
3435 log_error("Attempted to remove disk file system, and we can't allow that.");
3440 if (delete_root && !only_dirs)
3441 if (unlink(path) < 0 && errno != ENOENT)
3448 if (fstatfs(fd, &s) < 0) {
3449 close_nointr_nofail(fd);
3453 if (s.f_type != TMPFS_MAGIC &&
3454 s.f_type != RAMFS_MAGIC) {
3455 log_error("Attempted to remove disk file system, and we can't allow that.");
3456 close_nointr_nofail(fd);
3461 r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL);
3464 if (honour_sticky && file_is_priv_sticky(path) > 0)
3467 if (rmdir(path) < 0 && errno != ENOENT) {
3476 int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3477 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false);
3480 int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3481 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, true);
3484 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
3487 /* Under the assumption that we are running privileged we
3488 * first change the access mode and only then hand out
3489 * ownership to avoid a window where access is too open. */
3491 if (mode != (mode_t) -1)
3492 if (chmod(path, mode) < 0)
3495 if (uid != (uid_t) -1 || gid != (gid_t) -1)
3496 if (chown(path, uid, gid) < 0)
3502 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
3505 /* Under the assumption that we are running privileged we
3506 * first change the access mode and only then hand out
3507 * ownership to avoid a window where access is too open. */
3509 if (fchmod(fd, mode) < 0)
3512 if (fchown(fd, uid, gid) < 0)
3518 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
3522 /* Allocates the cpuset in the right size */
3525 if (!(r = CPU_ALLOC(n)))
3528 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
3529 CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
3539 if (errno != EINVAL)
3546 void status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) {
3548 static const char status_indent[] = " "; /* "[" STATUS "] " */
3550 struct iovec iovec[5];
3555 /* This is independent of logging, as status messages are
3556 * optional and go exclusively to the console. */
3558 if (vasprintf(&s, format, ap) < 0)
3561 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
3574 sl = status ? strlen(status_indent) : 0;
3580 e = ellipsize(s, emax, 75);
3590 if (!isempty(status)) {
3591 IOVEC_SET_STRING(iovec[n++], "[");
3592 IOVEC_SET_STRING(iovec[n++], status);
3593 IOVEC_SET_STRING(iovec[n++], "] ");
3595 IOVEC_SET_STRING(iovec[n++], status_indent);
3598 IOVEC_SET_STRING(iovec[n++], s);
3599 IOVEC_SET_STRING(iovec[n++], "\n");
3601 writev(fd, iovec, n);
3607 close_nointr_nofail(fd);
3610 void status_printf(const char *status, bool ellipse, const char *format, ...) {
3615 va_start(ap, format);
3616 status_vprintf(status, ellipse, format, ap);
3620 void status_welcome(void) {
3621 char *pretty_name = NULL, *ansi_color = NULL;
3622 const char *const_pretty = NULL, *const_color = NULL;
3625 if ((r = parse_env_file("/etc/os-release", NEWLINE,
3626 "PRETTY_NAME", &pretty_name,
3627 "ANSI_COLOR", &ansi_color,
3631 log_warning("Failed to read /etc/os-release: %s", strerror(-r));
3634 if (!pretty_name && !const_pretty)
3635 const_pretty = "Linux";
3637 if (!ansi_color && !const_color)
3642 "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
3643 const_color ? const_color : ansi_color,
3644 const_pretty ? const_pretty : pretty_name);
3650 char *replace_env(const char *format, char **env) {
3657 const char *e, *word = format;
3662 for (e = format; *e; e ++) {
3673 if (!(k = strnappend(r, word, e-word-1)))
3682 } else if (*e == '$') {
3683 if (!(k = strnappend(r, word, e-word)))
3699 if (!(t = strv_env_get_with_length(env, word+2, e-word-2)))
3702 if (!(k = strappend(r, t)))
3715 if (!(k = strnappend(r, word, e-word)))
3726 char **replace_env_argv(char **argv, char **env) {
3728 unsigned k = 0, l = 0;
3730 l = strv_length(argv);
3732 if (!(r = new(char*, l+1)))
3735 STRV_FOREACH(i, argv) {
3737 /* If $FOO appears as single word, replace it by the split up variable */
3738 if ((*i)[0] == '$' && (*i)[1] != '{') {
3743 if ((e = strv_env_get(env, *i+1))) {
3745 if (!(m = strv_split_quoted(e))) {
3756 if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
3765 memcpy(r + k, m, q * sizeof(char*));
3773 /* If ${FOO} appears as part of a word, replace it by the variable as-is */
3774 if (!(r[k++] = replace_env(*i, env))) {
3784 int fd_columns(int fd) {
3788 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3797 static unsigned columns_cached(bool cached) {
3798 static __thread int parsed_columns = 0, env_columns = -1;
3801 if (_likely_(parsed_columns > 0 && cached))
3802 return parsed_columns;
3804 if (_unlikely_(env_columns == -1)) {
3805 e = getenv("COLUMNS");
3807 env_columns = atoi(e);
3812 if (env_columns > 0) {
3813 parsed_columns = env_columns;
3814 return parsed_columns;
3817 if (parsed_columns <= 0 || !cached)
3818 parsed_columns = fd_columns(STDOUT_FILENO);
3820 if (parsed_columns <= 0)
3821 parsed_columns = 80;
3823 return parsed_columns;
3826 unsigned columns(void) {
3827 return columns_cached(true);
3830 unsigned columns_uncached(void) {
3831 return columns_cached(false);
3834 int fd_lines(int fd) {
3838 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3847 unsigned lines(void) {
3848 static __thread int parsed_lines = 0;
3851 if (_likely_(parsed_lines > 0))
3852 return parsed_lines;
3854 e = getenv("LINES");
3856 parsed_lines = atoi(e);
3858 if (parsed_lines <= 0)
3859 parsed_lines = fd_lines(STDOUT_FILENO);
3861 if (parsed_lines <= 0)
3864 return parsed_lines;
3867 int running_in_chroot(void) {
3873 /* Only works as root */
3875 if (stat("/proc/1/root", &a) < 0)
3878 if (stat("/", &b) < 0)
3882 a.st_dev != b.st_dev ||
3883 a.st_ino != b.st_ino;
3886 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
3891 assert(percent <= 100);
3892 assert(new_length >= 3);
3894 if (old_length <= 3 || old_length <= new_length)
3895 return strndup(s, old_length);
3897 r = new0(char, new_length+1);
3901 x = (new_length * percent) / 100;
3903 if (x > new_length - 3)
3911 s + old_length - (new_length - x - 3),
3912 new_length - x - 3);
3917 char *ellipsize(const char *s, size_t length, unsigned percent) {
3918 return ellipsize_mem(s, strlen(s), length, percent);
3921 int touch(const char *path) {
3926 if ((fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644)) < 0)
3929 close_nointr_nofail(fd);
3933 char *unquote(const char *s, const char* quotes) {
3941 if (strchr(quotes, s[0]) && s[l-1] == s[0])
3942 return strndup(s+1, l-2);
3947 char *normalize_env_assignment(const char *s) {
3948 char *name, *value, *p, *r;
3953 if (!(r = strdup(s)))
3959 if (!(name = strndup(s, p - s)))
3962 if (!(p = strdup(p+1))) {
3967 value = unquote(strstrip(p), QUOTES);
3975 if (asprintf(&r, "%s=%s", name, value) < 0)
3984 int wait_for_terminate(pid_t pid, siginfo_t *status) {
3995 if (waitid(P_PID, pid, status, WEXITED) < 0) {
4007 int wait_for_terminate_and_warn(const char *name, pid_t pid) {
4014 r = wait_for_terminate(pid, &status);
4016 log_warning("Failed to wait for %s: %s", name, strerror(-r));
4020 if (status.si_code == CLD_EXITED) {
4021 if (status.si_status != 0) {
4022 log_warning("%s failed with error code %i.", name, status.si_status);
4023 return status.si_status;
4026 log_debug("%s succeeded.", name);
4029 } else if (status.si_code == CLD_KILLED ||
4030 status.si_code == CLD_DUMPED) {
4032 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
4036 log_warning("%s failed due to unknown reason.", name);
4040 _noreturn_ void freeze(void) {
4042 /* Make sure nobody waits for us on a socket anymore */
4043 close_all_fds(NULL, 0);
4051 bool null_or_empty(struct stat *st) {
4054 if (S_ISREG(st->st_mode) && st->st_size <= 0)
4057 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
4063 int null_or_empty_path(const char *fn) {
4068 if (stat(fn, &st) < 0)
4071 return null_or_empty(&st);
4074 DIR *xopendirat(int fd, const char *name, int flags) {
4078 if ((nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags)) < 0)
4081 if (!(d = fdopendir(nfd))) {
4082 close_nointr_nofail(nfd);
4089 int signal_from_string_try_harder(const char *s) {
4093 if ((signo = signal_from_string(s)) <= 0)
4094 if (startswith(s, "SIG"))
4095 return signal_from_string(s+3);
4100 void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) {
4106 if (!dual_timestamp_is_set(t))
4109 fprintf(f, "%s=%llu %llu\n",
4111 (unsigned long long) t->realtime,
4112 (unsigned long long) t->monotonic);
4115 void dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
4116 unsigned long long a, b;
4121 if (sscanf(value, "%lli %llu", &a, &b) != 2)
4122 log_debug("Failed to parse finish timestamp value %s", value);
4129 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
4133 /* FIXME: to follow udev's logic 100% we need to leave valid
4134 * UTF8 chars unescaped */
4136 u = unquote(tagvalue, "\"\'");
4140 t = xescape(u, "/ ");
4146 r = asprintf(&dn, "/dev/disk/by-%s/%s", by, t);
4155 char *fstab_node_to_udev_node(const char *p) {
4156 if (startswith(p, "LABEL="))
4157 return tag_to_udev_node(p+6, "label");
4159 if (startswith(p, "UUID="))
4160 return tag_to_udev_node(p+5, "uuid");
4162 if (startswith(p, "PARTUUID="))
4163 return tag_to_udev_node(p+9, "partuuid");
4165 if (startswith(p, "PARTLABEL="))
4166 return tag_to_udev_node(p+10, "partlabel");
4171 bool tty_is_vc(const char *tty) {
4174 if (startswith(tty, "/dev/"))
4177 return vtnr_from_tty(tty) >= 0;
4180 bool tty_is_console(const char *tty) {
4183 if (startswith(tty, "/dev/"))
4186 return streq(tty, "console");
4189 int vtnr_from_tty(const char *tty) {
4194 if (startswith(tty, "/dev/"))
4197 if (!startswith(tty, "tty") )
4200 if (tty[3] < '0' || tty[3] > '9')
4203 r = safe_atoi(tty+3, &i);
4207 if (i < 0 || i > 63)
4213 bool tty_is_vc_resolve(const char *tty) {
4214 char *active = NULL;
4219 if (startswith(tty, "/dev/"))
4222 /* Resolve where /dev/console is pointing to, if /sys is
4223 * actually ours (i.e. not read-only-mounted which is a sign
4224 * for container setups) */
4225 if (streq(tty, "console") && path_is_read_only_fs("/sys") <= 0)
4226 if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) {
4227 /* If multiple log outputs are configured the
4228 * last one is what /dev/console points to */
4229 tty = strrchr(active, ' ');
4242 const char *default_term_for_tty(const char *tty) {
4245 return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102";
4248 bool dirent_is_file(const struct dirent *de) {
4251 if (ignore_file(de->d_name))
4254 if (de->d_type != DT_REG &&
4255 de->d_type != DT_LNK &&
4256 de->d_type != DT_UNKNOWN)
4262 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
4265 if (de->d_type != DT_REG &&
4266 de->d_type != DT_LNK &&
4267 de->d_type != DT_UNKNOWN)
4270 if (ignore_file_allow_backup(de->d_name))
4273 return endswith(de->d_name, suffix);
4276 void execute_directory(const char *directory, DIR *d, char *argv[]) {
4279 Hashmap *pids = NULL;
4283 /* Executes all binaries in a directory in parallel and waits
4284 * until all they all finished. */
4287 if (!(_d = opendir(directory))) {
4289 if (errno == ENOENT)
4292 log_error("Failed to enumerate directory %s: %m", directory);
4299 if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) {
4300 log_error("Failed to allocate set.");
4304 while ((de = readdir(d))) {
4309 if (!dirent_is_file(de))
4312 if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
4317 if ((pid = fork()) < 0) {
4318 log_error("Failed to fork: %m");
4336 log_error("Failed to execute %s: %m", path);
4337 _exit(EXIT_FAILURE);
4340 log_debug("Spawned %s as %lu", path, (unsigned long) pid);
4342 if ((k = hashmap_put(pids, UINT_TO_PTR(pid), path)) < 0) {
4343 log_error("Failed to add PID to set: %s", strerror(-k));
4348 while (!hashmap_isempty(pids)) {
4349 pid_t pid = PTR_TO_UINT(hashmap_first_key(pids));
4354 if (waitid(P_PID, pid, &si, WEXITED) < 0) {
4359 log_error("waitid() failed: %m");
4363 if ((path = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) {
4364 if (!is_clean_exit(si.si_code, si.si_status, NULL)) {
4365 if (si.si_code == CLD_EXITED)
4366 log_error("%s exited with exit status %i.", path, si.si_status);
4368 log_error("%s terminated by signal %s.", path, signal_to_string(si.si_status));
4370 log_debug("%s exited successfully.", path);
4381 hashmap_free_free(pids);
4384 int kill_and_sigcont(pid_t pid, int sig) {
4387 r = kill(pid, sig) < 0 ? -errno : 0;
4395 bool nulstr_contains(const char*nulstr, const char *needle) {
4401 NULSTR_FOREACH(i, nulstr)
4402 if (streq(i, needle))
4408 bool plymouth_running(void) {
4409 return access("/run/plymouth/pid", F_OK) >= 0;
4412 char* strshorten(char *s, size_t l) {
4421 static bool hostname_valid_char(char c) {
4423 (c >= 'a' && c <= 'z') ||
4424 (c >= 'A' && c <= 'Z') ||
4425 (c >= '0' && c <= '9') ||
4431 bool hostname_is_valid(const char *s) {
4437 for (p = s; *p; p++)
4438 if (!hostname_valid_char(*p))
4441 if (p-s > HOST_NAME_MAX)
4447 char* hostname_cleanup(char *s) {
4450 for (p = s, d = s; *p; p++)
4451 if ((*p >= 'a' && *p <= 'z') ||
4452 (*p >= 'A' && *p <= 'Z') ||
4453 (*p >= '0' && *p <= '9') ||
4461 strshorten(s, HOST_NAME_MAX);
4465 int pipe_eof(int fd) {
4466 struct pollfd pollfd;
4471 pollfd.events = POLLIN|POLLHUP;
4473 r = poll(&pollfd, 1, 0);
4480 return pollfd.revents & POLLHUP;
4483 int fd_wait_for_event(int fd, int event, usec_t t) {
4484 struct pollfd pollfd;
4489 pollfd.events = event;
4491 r = poll(&pollfd, 1, t == (usec_t) -1 ? -1 : (int) (t / USEC_PER_MSEC));
4498 return pollfd.revents;
4501 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
4512 t = new(char, strlen(path) + 1 + 6 + 1);
4516 fn = path_get_file_name(path);
4520 stpcpy(stpcpy(t+k+1, fn), "XXXXXX");
4522 fd = mkostemp(t, O_WRONLY|O_CLOEXEC);
4528 f = fdopen(fd, "we");
4541 int terminal_vhangup_fd(int fd) {
4544 if (ioctl(fd, TIOCVHANGUP) < 0)
4550 int terminal_vhangup(const char *name) {
4553 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4557 r = terminal_vhangup_fd(fd);
4558 close_nointr_nofail(fd);
4563 int vt_disallocate(const char *name) {
4567 /* Deallocate the VT if possible. If not possible
4568 * (i.e. because it is the active one), at least clear it
4569 * entirely (including the scrollback buffer) */
4571 if (!startswith(name, "/dev/"))
4574 if (!tty_is_vc(name)) {
4575 /* So this is not a VT. I guess we cannot deallocate
4576 * it then. But let's at least clear the screen */
4578 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4583 "\033[r" /* clear scrolling region */
4584 "\033[H" /* move home */
4585 "\033[2J", /* clear screen */
4587 close_nointr_nofail(fd);
4592 if (!startswith(name, "/dev/tty"))
4595 r = safe_atou(name+8, &u);
4602 /* Try to deallocate */
4603 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
4607 r = ioctl(fd, VT_DISALLOCATE, u);
4608 close_nointr_nofail(fd);
4616 /* Couldn't deallocate, so let's clear it fully with
4618 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4623 "\033[r" /* clear scrolling region */
4624 "\033[H" /* move home */
4625 "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
4627 close_nointr_nofail(fd);
4632 int copy_file(const char *from, const char *to) {
4638 fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
4642 fdt = open(to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY, 0644);
4644 close_nointr_nofail(fdf);
4652 n = read(fdf, buf, sizeof(buf));
4656 close_nointr_nofail(fdf);
4667 k = loop_write(fdt, buf, n, false);
4669 r = k < 0 ? k : (errno ? -errno : -EIO);
4671 close_nointr_nofail(fdf);
4679 close_nointr_nofail(fdf);
4680 r = close_nointr(fdt);
4690 int symlink_or_copy(const char *from, const char *to) {
4691 char *pf = NULL, *pt = NULL;
4698 if (path_get_parent(from, &pf) < 0 ||
4699 path_get_parent(to, &pt) < 0) {
4704 if (stat(pf, &a) < 0 ||
4710 if (a.st_dev != b.st_dev) {
4714 return copy_file(from, to);
4717 if (symlink(from, to) < 0) {
4731 int symlink_or_copy_atomic(const char *from, const char *to) {
4735 unsigned long long ull;
4742 t = new(char, strlen(to) + 1 + 16 + 1);
4746 fn = path_get_file_name(to);
4750 x = stpcpy(t+k+1, fn);
4753 for (i = 0; i < 16; i++) {
4754 *(x++) = hexchar(ull & 0xF);
4760 r = symlink_or_copy(from, t);
4767 if (rename(t, to) < 0) {
4778 bool display_is_local(const char *display) {
4782 display[0] == ':' &&
4783 display[1] >= '0' &&
4787 int socket_from_display(const char *display, char **path) {
4794 if (!display_is_local(display))
4797 k = strspn(display+1, "0123456789");
4799 f = new(char, sizeof("/tmp/.X11-unix/X") + k);
4803 c = stpcpy(f, "/tmp/.X11-unix/X");
4804 memcpy(c, display+1, k);
4813 const char **username,
4814 uid_t *uid, gid_t *gid,
4816 const char **shell) {
4824 /* We enforce some special rules for uid=0: in order to avoid
4825 * NSS lookups for root we hardcode its data. */
4827 if (streq(*username, "root") || streq(*username, "0")) {
4845 if (parse_uid(*username, &u) >= 0) {
4849 /* If there are multiple users with the same id, make
4850 * sure to leave $USER to the configured value instead
4851 * of the first occurrence in the database. However if
4852 * the uid was configured by a numeric uid, then let's
4853 * pick the real username from /etc/passwd. */
4855 *username = p->pw_name;
4858 p = getpwnam(*username);
4862 return errno != 0 ? -errno : -ESRCH;
4874 *shell = p->pw_shell;
4879 int get_group_creds(const char **groupname, gid_t *gid) {
4885 /* We enforce some special rules for gid=0: in order to avoid
4886 * NSS lookups for root we hardcode its data. */
4888 if (streq(*groupname, "root") || streq(*groupname, "0")) {
4889 *groupname = "root";
4897 if (parse_gid(*groupname, &id) >= 0) {
4902 *groupname = g->gr_name;
4905 g = getgrnam(*groupname);
4909 return errno != 0 ? -errno : -ESRCH;
4917 int in_group(const char *name) {
4919 int ngroups_max, r, i;
4921 r = get_group_creds(&name, &gid);
4925 if (getgid() == gid)
4928 if (getegid() == gid)
4931 ngroups_max = sysconf(_SC_NGROUPS_MAX);
4932 assert(ngroups_max > 0);
4934 gids = alloca(sizeof(gid_t) * ngroups_max);
4936 r = getgroups(ngroups_max, gids);
4940 for (i = 0; i < r; i++)
4947 int glob_exists(const char *path) {
4955 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
4957 if (k == GLOB_NOMATCH)
4959 else if (k == GLOB_NOSPACE)
4962 r = !strv_isempty(g.gl_pathv);
4964 r = errno ? -errno : -EIO;
4971 int dirent_ensure_type(DIR *d, struct dirent *de) {
4977 if (de->d_type != DT_UNKNOWN)
4980 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
4984 S_ISREG(st.st_mode) ? DT_REG :
4985 S_ISDIR(st.st_mode) ? DT_DIR :
4986 S_ISLNK(st.st_mode) ? DT_LNK :
4987 S_ISFIFO(st.st_mode) ? DT_FIFO :
4988 S_ISSOCK(st.st_mode) ? DT_SOCK :
4989 S_ISCHR(st.st_mode) ? DT_CHR :
4990 S_ISBLK(st.st_mode) ? DT_BLK :
4996 int in_search_path(const char *path, char **search) {
5000 r = path_get_parent(path, &parent);
5006 STRV_FOREACH(i, search) {
5007 if (path_equal(parent, *i)) {
5018 int get_files_in_directory(const char *path, char ***list) {
5026 /* Returns all files in a directory in *list, and the number
5027 * of files as return value. If list is NULL returns only the
5035 struct dirent buffer, *de;
5038 k = readdir_r(d, &buffer, &de);
5047 dirent_ensure_type(d, de);
5049 if (!dirent_is_file(de))
5053 if ((unsigned) r >= n) {
5057 t = realloc(l, sizeof(char*) * n);
5066 assert((unsigned) r < n);
5068 l[r] = strdup(de->d_name);
5092 char *strjoin(const char *x, ...) {
5105 t = va_arg(ap, const char *);
5128 t = va_arg(ap, const char *);
5142 bool is_main_thread(void) {
5143 static __thread int cached = 0;
5145 if (_unlikely_(cached == 0))
5146 cached = getpid() == gettid() ? 1 : -1;
5151 int block_get_whole_disk(dev_t d, dev_t *ret) {
5158 /* If it has a queue this is good enough for us */
5159 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
5162 r = access(p, F_OK);
5170 /* If it is a partition find the originating device */
5171 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
5174 r = access(p, F_OK);
5180 /* Get parent dev_t */
5181 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
5184 r = read_one_line_file(p, &s);
5190 r = sscanf(s, "%u:%u", &m, &n);
5196 /* Only return this if it is really good enough for us. */
5197 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
5200 r = access(p, F_OK);
5204 *ret = makedev(m, n);
5211 int file_is_priv_sticky(const char *p) {
5216 if (lstat(p, &st) < 0)
5220 (st.st_uid == 0 || st.st_uid == getuid()) &&
5221 (st.st_mode & S_ISVTX);
5224 static const char *const ioprio_class_table[] = {
5225 [IOPRIO_CLASS_NONE] = "none",
5226 [IOPRIO_CLASS_RT] = "realtime",
5227 [IOPRIO_CLASS_BE] = "best-effort",
5228 [IOPRIO_CLASS_IDLE] = "idle"
5231 DEFINE_STRING_TABLE_LOOKUP(ioprio_class, int);
5233 static const char *const sigchld_code_table[] = {
5234 [CLD_EXITED] = "exited",
5235 [CLD_KILLED] = "killed",
5236 [CLD_DUMPED] = "dumped",
5237 [CLD_TRAPPED] = "trapped",
5238 [CLD_STOPPED] = "stopped",
5239 [CLD_CONTINUED] = "continued",
5242 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
5244 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
5245 [LOG_FAC(LOG_KERN)] = "kern",
5246 [LOG_FAC(LOG_USER)] = "user",
5247 [LOG_FAC(LOG_MAIL)] = "mail",
5248 [LOG_FAC(LOG_DAEMON)] = "daemon",
5249 [LOG_FAC(LOG_AUTH)] = "auth",
5250 [LOG_FAC(LOG_SYSLOG)] = "syslog",
5251 [LOG_FAC(LOG_LPR)] = "lpr",
5252 [LOG_FAC(LOG_NEWS)] = "news",
5253 [LOG_FAC(LOG_UUCP)] = "uucp",
5254 [LOG_FAC(LOG_CRON)] = "cron",
5255 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
5256 [LOG_FAC(LOG_FTP)] = "ftp",
5257 [LOG_FAC(LOG_LOCAL0)] = "local0",
5258 [LOG_FAC(LOG_LOCAL1)] = "local1",
5259 [LOG_FAC(LOG_LOCAL2)] = "local2",
5260 [LOG_FAC(LOG_LOCAL3)] = "local3",
5261 [LOG_FAC(LOG_LOCAL4)] = "local4",
5262 [LOG_FAC(LOG_LOCAL5)] = "local5",
5263 [LOG_FAC(LOG_LOCAL6)] = "local6",
5264 [LOG_FAC(LOG_LOCAL7)] = "local7"
5267 DEFINE_STRING_TABLE_LOOKUP(log_facility_unshifted, int);
5269 static const char *const log_level_table[] = {
5270 [LOG_EMERG] = "emerg",
5271 [LOG_ALERT] = "alert",
5272 [LOG_CRIT] = "crit",
5274 [LOG_WARNING] = "warning",
5275 [LOG_NOTICE] = "notice",
5276 [LOG_INFO] = "info",
5277 [LOG_DEBUG] = "debug"
5280 DEFINE_STRING_TABLE_LOOKUP(log_level, int);
5282 static const char* const sched_policy_table[] = {
5283 [SCHED_OTHER] = "other",
5284 [SCHED_BATCH] = "batch",
5285 [SCHED_IDLE] = "idle",
5286 [SCHED_FIFO] = "fifo",
5290 DEFINE_STRING_TABLE_LOOKUP(sched_policy, int);
5292 static const char* const rlimit_table[] = {
5293 [RLIMIT_CPU] = "LimitCPU",
5294 [RLIMIT_FSIZE] = "LimitFSIZE",
5295 [RLIMIT_DATA] = "LimitDATA",
5296 [RLIMIT_STACK] = "LimitSTACK",
5297 [RLIMIT_CORE] = "LimitCORE",
5298 [RLIMIT_RSS] = "LimitRSS",
5299 [RLIMIT_NOFILE] = "LimitNOFILE",
5300 [RLIMIT_AS] = "LimitAS",
5301 [RLIMIT_NPROC] = "LimitNPROC",
5302 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
5303 [RLIMIT_LOCKS] = "LimitLOCKS",
5304 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
5305 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
5306 [RLIMIT_NICE] = "LimitNICE",
5307 [RLIMIT_RTPRIO] = "LimitRTPRIO",
5308 [RLIMIT_RTTIME] = "LimitRTTIME"
5311 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
5313 static const char* const ip_tos_table[] = {
5314 [IPTOS_LOWDELAY] = "low-delay",
5315 [IPTOS_THROUGHPUT] = "throughput",
5316 [IPTOS_RELIABILITY] = "reliability",
5317 [IPTOS_LOWCOST] = "low-cost",
5320 DEFINE_STRING_TABLE_LOOKUP(ip_tos, int);
5322 static const char *const __signal_table[] = {
5339 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
5350 [SIGVTALRM] = "VTALRM",
5352 [SIGWINCH] = "WINCH",
5358 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
5360 const char *signal_to_string(int signo) {
5361 static __thread char buf[12];
5364 name = __signal_to_string(signo);
5368 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
5369 snprintf(buf, sizeof(buf) - 1, "RTMIN+%d", signo - SIGRTMIN);
5371 snprintf(buf, sizeof(buf) - 1, "%d", signo);
5376 int signal_from_string(const char *s) {
5381 signo =__signal_from_string(s);
5385 if (startswith(s, "RTMIN+")) {
5389 if (safe_atou(s, &u) >= 0) {
5390 signo = (int) u + offset;
5391 if (signo > 0 && signo < _NSIG)
5397 bool kexec_loaded(void) {
5398 bool loaded = false;
5401 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
5409 int strdup_or_null(const char *a, char **b) {
5427 int prot_from_flags(int flags) {
5429 switch (flags & O_ACCMODE) {
5438 return PROT_READ|PROT_WRITE;
5445 char *format_bytes(char *buf, size_t l, off_t t) {
5448 static const struct {
5452 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5453 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5454 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
5455 { "G", 1024ULL*1024ULL*1024ULL },
5456 { "M", 1024ULL*1024ULL },
5460 for (i = 0; i < ELEMENTSOF(table); i++) {
5462 if (t >= table[i].factor) {
5465 (unsigned long long) (t / table[i].factor),
5466 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
5473 snprintf(buf, l, "%lluB", (unsigned long long) t);
5481 void* memdup(const void *p, size_t l) {
5494 int fd_inc_sndbuf(int fd, size_t n) {
5496 socklen_t l = sizeof(value);
5498 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
5500 l == sizeof(value) &&
5501 (size_t) value >= n*2)
5505 r = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value));
5512 int fd_inc_rcvbuf(int fd, size_t n) {
5514 socklen_t l = sizeof(value);
5516 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
5518 l == sizeof(value) &&
5519 (size_t) value >= n*2)
5523 r = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value));
5530 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
5531 pid_t parent_pid, agent_pid;
5533 bool stdout_is_tty, stderr_is_tty;
5541 parent_pid = getpid();
5543 /* Spawns a temporary TTY agent, making sure it goes away when
5550 if (agent_pid != 0) {
5557 * Make sure the agent goes away when the parent dies */
5558 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
5559 _exit(EXIT_FAILURE);
5561 /* Check whether our parent died before we were able
5562 * to set the death signal */
5563 if (getppid() != parent_pid)
5564 _exit(EXIT_SUCCESS);
5566 /* Don't leak fds to the agent */
5567 close_all_fds(except, n_except);
5569 stdout_is_tty = isatty(STDOUT_FILENO);
5570 stderr_is_tty = isatty(STDERR_FILENO);
5572 if (!stdout_is_tty || !stderr_is_tty) {
5573 /* Detach from stdout/stderr. and reopen
5574 * /dev/tty for them. This is important to
5575 * ensure that when systemctl is started via
5576 * popen() or a similar call that expects to
5577 * read EOF we actually do generate EOF and
5578 * not delay this indefinitely by because we
5579 * keep an unused copy of stdin around. */
5580 fd = open("/dev/tty", O_WRONLY);
5582 log_error("Failed to open /dev/tty: %m");
5583 _exit(EXIT_FAILURE);
5587 dup2(fd, STDOUT_FILENO);
5590 dup2(fd, STDERR_FILENO);
5596 /* Count arguments */
5598 for (n = 0; va_arg(ap, char*); n++)
5603 l = alloca(sizeof(char *) * (n + 1));
5605 /* Fill in arguments */
5607 for (i = 0; i <= n; i++)
5608 l[i] = va_arg(ap, char*);
5612 _exit(EXIT_FAILURE);
5615 int setrlimit_closest(int resource, const struct rlimit *rlim) {
5616 struct rlimit highest, fixed;
5620 if (setrlimit(resource, rlim) >= 0)
5626 /* So we failed to set the desired setrlimit, then let's try
5627 * to get as close as we can */
5628 assert_se(getrlimit(resource, &highest) == 0);
5630 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
5631 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
5633 if (setrlimit(resource, &fixed) < 0)
5639 int getenv_for_pid(pid_t pid, const char *field, char **_value) {
5640 char path[sizeof("/proc/")-1+10+sizeof("/environ")], *value = NULL;
5652 snprintf(path, sizeof(path), "/proc/%lu/environ", (unsigned long) pid);
5655 f = fopen(path, "re");
5663 char line[LINE_MAX];
5666 for (i = 0; i < sizeof(line)-1; i++) {
5670 if (_unlikely_(c == EOF)) {
5680 if (memcmp(line, field, l) == 0 && line[l] == '=') {
5681 value = strdup(line + l + 1);
5701 int can_sleep(const char *type) {
5702 char *p, *w, *state;
5709 r = read_one_line_file("/sys/power/state", &p);
5711 return r == -ENOENT ? 0 : r;
5715 FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state) {
5716 if (l == k && strncmp(w, type, l) == 0) {
5726 bool is_valid_documentation_url(const char *url) {
5729 if (startswith(url, "http://") && url[7])
5732 if (startswith(url, "https://") && url[8])
5735 if (startswith(url, "file:") && url[5])
5738 if (startswith(url, "info:") && url[5])
5741 if (startswith(url, "man:") && url[4])
5747 bool in_initrd(void) {
5748 static int saved = -1;
5754 /* We make two checks here:
5756 * 1. the flag file /etc/initrd-release must exist
5757 * 2. the root file system must be a memory file system
5759 * The second check is extra paranoia, since misdetecting an
5760 * initrd can have bad bad consequences due the initrd
5761 * emptying when transititioning to the main systemd.
5764 saved = access("/etc/initrd-release", F_OK) >= 0 &&
5765 statfs("/", &s) >= 0 &&
5766 (s.f_type == TMPFS_MAGIC || s.f_type == RAMFS_MAGIC);
5771 void warn_melody(void) {
5774 fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
5778 /* Yeah, this is synchronous. Kinda sucks. Bute well... */
5780 ioctl(fd, KIOCSOUND, (int)(1193180/440));
5781 usleep(125*USEC_PER_MSEC);
5783 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5784 usleep(125*USEC_PER_MSEC);
5786 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5787 usleep(125*USEC_PER_MSEC);
5789 ioctl(fd, KIOCSOUND, 0);
5790 close_nointr_nofail(fd);
5793 int make_console_stdio(void) {
5796 /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
5798 fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1);
5800 log_error("Failed to acquire terminal: %s", strerror(-fd));
5806 log_error("Failed to duplicate terminal fd: %s", strerror(-r));
5813 int get_home_dir(char **_h) {
5821 /* Take the user specified one */
5832 /* Hardcode home directory for root to avoid NSS */
5835 h = strdup("/root");
5843 /* Check the database... */
5847 return errno ? -errno : -ENOENT;
5849 if (!path_is_absolute(p->pw_dir))
5852 h = strdup(p->pw_dir);
5860 int get_shell(char **_sh) {
5868 /* Take the user specified one */
5869 e = getenv("SHELL");
5879 /* Hardcode home directory for root to avoid NSS */
5882 sh = strdup("/bin/sh");
5890 /* Check the database... */
5894 return errno ? -errno : -ESRCH;
5896 if (!path_is_absolute(p->pw_shell))
5899 sh = strdup(p->pw_shell);