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>
65 #include "path-util.h"
66 #include "exit-status.h"
70 char **saved_argv = NULL;
72 size_t page_size(void) {
73 static __thread size_t pgsz = 0;
76 if (_likely_(pgsz > 0))
79 assert_se((r = sysconf(_SC_PAGESIZE)) > 0);
86 bool streq_ptr(const char *a, const char *b) {
88 /* Like streq(), but tries to make sense of NULL pointers */
99 usec_t now(clockid_t clock_id) {
102 assert_se(clock_gettime(clock_id, &ts) == 0);
104 return timespec_load(&ts);
107 dual_timestamp* dual_timestamp_get(dual_timestamp *ts) {
110 ts->realtime = now(CLOCK_REALTIME);
111 ts->monotonic = now(CLOCK_MONOTONIC);
116 dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) {
125 delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
127 ts->monotonic = now(CLOCK_MONOTONIC);
129 if ((int64_t) ts->monotonic > delta)
130 ts->monotonic -= delta;
138 usec_t timespec_load(const struct timespec *ts) {
142 (usec_t) ts->tv_sec * USEC_PER_SEC +
143 (usec_t) ts->tv_nsec / NSEC_PER_USEC;
146 struct timespec *timespec_store(struct timespec *ts, usec_t u) {
149 ts->tv_sec = (time_t) (u / USEC_PER_SEC);
150 ts->tv_nsec = (long int) ((u % USEC_PER_SEC) * NSEC_PER_USEC);
155 usec_t timeval_load(const struct timeval *tv) {
159 (usec_t) tv->tv_sec * USEC_PER_SEC +
160 (usec_t) tv->tv_usec;
163 struct timeval *timeval_store(struct timeval *tv, usec_t u) {
166 tv->tv_sec = (time_t) (u / USEC_PER_SEC);
167 tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC);
172 bool endswith(const char *s, const char *postfix) {
179 pl = strlen(postfix);
187 return memcmp(s + sl - pl, postfix, pl) == 0;
190 bool startswith(const char *s, const char *prefix) {
205 return memcmp(s, prefix, pl) == 0;
208 bool startswith_no_case(const char *s, const char *prefix) {
224 for(i = 0; i < pl; ++i) {
225 if (tolower(s[i]) != tolower(prefix[i]))
232 bool first_word(const char *s, const char *word) {
247 if (memcmp(s, word, wl) != 0)
251 strchr(WHITESPACE, s[wl]);
254 int close_nointr(int fd) {
269 void close_nointr_nofail(int fd) {
270 int saved_errno = errno;
272 /* like close_nointr() but cannot fail, and guarantees errno
275 assert_se(close_nointr(fd) == 0);
280 void close_many(const int fds[], unsigned n_fd) {
283 for (i = 0; i < n_fd; i++)
284 close_nointr_nofail(fds[i]);
287 int parse_boolean(const char *v) {
290 if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
292 else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
298 int parse_pid(const char *s, pid_t* ret_pid) {
299 unsigned long ul = 0;
306 if ((r = safe_atolu(s, &ul)) < 0)
311 if ((unsigned long) pid != ul)
321 int parse_uid(const char *s, uid_t* ret_uid) {
322 unsigned long ul = 0;
329 if ((r = safe_atolu(s, &ul)) < 0)
334 if ((unsigned long) uid != ul)
341 int safe_atou(const char *s, unsigned *ret_u) {
349 l = strtoul(s, &x, 0);
351 if (!x || *x || errno)
352 return errno ? -errno : -EINVAL;
354 if ((unsigned long) (unsigned) l != l)
357 *ret_u = (unsigned) l;
361 int safe_atoi(const char *s, int *ret_i) {
369 l = strtol(s, &x, 0);
371 if (!x || *x || errno)
372 return errno ? -errno : -EINVAL;
374 if ((long) (int) l != l)
381 int safe_atollu(const char *s, long long unsigned *ret_llu) {
383 unsigned long long l;
389 l = strtoull(s, &x, 0);
391 if (!x || *x || errno)
392 return errno ? -errno : -EINVAL;
398 int safe_atolli(const char *s, long long int *ret_lli) {
406 l = strtoll(s, &x, 0);
408 if (!x || *x || errno)
409 return errno ? -errno : -EINVAL;
415 /* Split a string into words. */
416 char *split(const char *c, size_t *l, const char *separator, char **state) {
419 current = *state ? *state : (char*) c;
421 if (!*current || *c == 0)
424 current += strspn(current, separator);
425 *l = strcspn(current, separator);
428 return (char*) current;
431 /* Split a string into words, but consider strings enclosed in '' and
432 * "" as words even if they include spaces. */
433 char *split_quoted(const char *c, size_t *l, char **state) {
435 bool escaped = false;
437 current = *state ? *state : (char*) c;
439 if (!*current || *c == 0)
442 current += strspn(current, WHITESPACE);
444 if (*current == '\'') {
447 for (e = current; *e; e++) {
457 *state = *e == 0 ? e : e+1;
458 } else if (*current == '\"') {
461 for (e = current; *e; e++) {
471 *state = *e == 0 ? e : e+1;
473 for (e = current; *e; e++) {
478 else if (strchr(WHITESPACE, *e))
485 return (char*) current;
488 int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
491 char fn[PATH_MAX], line[LINE_MAX], *p;
497 assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1));
500 if (!(f = fopen(fn, "re")))
503 if (!(fgets(line, sizeof(line), f))) {
504 r = feof(f) ? -EIO : -errno;
511 /* Let's skip the pid and comm fields. The latter is enclosed
512 * in () but does not escape any () in its value, so let's
513 * skip over it manually */
515 if (!(p = strrchr(line, ')')))
526 if ((long unsigned) (pid_t) ppid != ppid)
529 *_ppid = (pid_t) ppid;
534 int get_starttime_of_pid(pid_t pid, unsigned long long *st) {
537 char fn[PATH_MAX], line[LINE_MAX], *p;
542 assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1));
545 if (!(f = fopen(fn, "re")))
548 if (!(fgets(line, sizeof(line), f))) {
549 r = feof(f) ? -EIO : -errno;
556 /* Let's skip the pid and comm fields. The latter is enclosed
557 * in () but does not escape any () in its value, so let's
558 * skip over it manually */
560 if (!(p = strrchr(line, ')')))
581 "%*d " /* priority */
583 "%*d " /* num_threads */
584 "%*d " /* itrealvalue */
585 "%llu " /* starttime */,
592 int write_one_line_file(const char *fn, const char *line) {
604 if (fputs(line, f) < 0) {
609 if (!endswith(line, "\n"))
627 int fchmod_umask(int fd, mode_t m) {
632 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
638 int write_one_line_file_atomic(const char *fn, const char *line) {
646 r = fopen_temporary(fn, &f, &p);
650 fchmod_umask(fileno(f), 0644);
653 if (fputs(line, f) < 0) {
658 if (!endswith(line, "\n"))
669 if (rename(p, fn) < 0)
685 int read_one_line_file(const char *fn, char **line) {
688 char t[LINE_MAX], *c;
697 if (!fgets(t, sizeof(t), f)) {
723 int read_full_file(const char *fn, char **contents, size_t *size) {
730 if (!(f = fopen(fn, "re")))
733 if (fstat(fileno(f), &st) < 0) {
739 if (st.st_size > 4*1024*1024) {
744 n = st.st_size > 0 ? st.st_size : LINE_MAX;
751 if (!(t = realloc(buf, n+1))) {
757 k = fread(buf + l, 1, n - l, f);
772 if (n > 4*1024*1024) {
796 const char *separator, ...) {
799 char *contents = NULL, *p;
804 if ((r = read_full_file(fname, &contents, NULL)) < 0)
809 const char *key = NULL;
811 p += strspn(p, separator);
812 p += strspn(p, WHITESPACE);
817 if (!strchr(COMMENTS, *p)) {
821 va_start(ap, separator);
822 while ((key = va_arg(ap, char *))) {
826 value = va_arg(ap, char **);
829 if (strncmp(p, key, n) != 0 ||
834 n = strcspn(p, separator);
837 strchr(QUOTES, p[0]) &&
839 v = strndup(p+1, n-2);
850 /* return empty value strings as NULL */
867 p += strcspn(p, separator);
886 if (!(f = fopen(fname, "re")))
890 char l[LINE_MAX], *p, *u;
893 if (!fgets(l, sizeof(l), f)) {
906 if (strchr(COMMENTS, *p))
909 if (!(u = normalize_env_assignment(p))) {
910 log_error("Out of memory");
915 t = strv_append(m, u);
919 log_error("Out of memory");
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 = join("[", 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(const char *s, size_t length) {
1571 /* Undoes C style string escaping */
1573 r = new(char, length+1);
1577 for (f = s, t = r; f < s + length; f++) {
1620 /* This is an extension of the XDG syntax files */
1625 /* hexadecimal encoding */
1628 a = unhexchar(f[1]);
1629 b = unhexchar(f[2]);
1631 if (a < 0 || b < 0) {
1632 /* Invalid escape code, let's take it literal then */
1636 *(t++) = (char) ((a << 4) | b);
1651 /* octal encoding */
1654 a = unoctchar(f[0]);
1655 b = unoctchar(f[1]);
1656 c = unoctchar(f[2]);
1658 if (a < 0 || b < 0 || c < 0) {
1659 /* Invalid escape code, let's take it literal then */
1663 *(t++) = (char) ((a << 6) | (b << 3) | c);
1671 /* premature end of string.*/
1676 /* Invalid escape code, let's take it literal then */
1688 char *cunescape(const char *s) {
1689 return cunescape_length(s, strlen(s));
1692 char *xescape(const char *s, const char *bad) {
1696 /* Escapes all chars in bad, in addition to \ and all special
1697 * chars, in \xFF style escaping. May be reversed with
1700 if (!(r = new(char, strlen(s)*4+1)))
1703 for (f = s, t = r; *f; f++) {
1705 if ((*f < ' ') || (*f >= 127) ||
1706 (*f == '\\') || strchr(bad, *f)) {
1709 *(t++) = hexchar(*f >> 4);
1710 *(t++) = hexchar(*f);
1720 char *bus_path_escape(const char *s) {
1726 /* Escapes all chars that D-Bus' object path cannot deal
1727 * with. Can be reverse with bus_path_unescape() */
1729 if (!(r = new(char, strlen(s)*3+1)))
1732 for (f = s, t = r; *f; f++) {
1734 if (!(*f >= 'A' && *f <= 'Z') &&
1735 !(*f >= 'a' && *f <= 'z') &&
1736 !(*f >= '0' && *f <= '9')) {
1738 *(t++) = hexchar(*f >> 4);
1739 *(t++) = hexchar(*f);
1749 char *bus_path_unescape(const char *f) {
1754 if (!(r = strdup(f)))
1757 for (t = r; *f; f++) {
1762 if ((a = unhexchar(f[1])) < 0 ||
1763 (b = unhexchar(f[2])) < 0) {
1764 /* Invalid escape code, let's take it literal then */
1767 *(t++) = (char) ((a << 4) | b);
1779 char *ascii_strlower(char *t) {
1784 for (p = t; *p; p++)
1785 if (*p >= 'A' && *p <= 'Z')
1786 *p = *p - 'A' + 'a';
1791 bool ignore_file(const char *filename) {
1795 filename[0] == '.' ||
1796 streq(filename, "lost+found") ||
1797 streq(filename, "aquota.user") ||
1798 streq(filename, "aquota.group") ||
1799 endswith(filename, "~") ||
1800 endswith(filename, ".rpmnew") ||
1801 endswith(filename, ".rpmsave") ||
1802 endswith(filename, ".rpmorig") ||
1803 endswith(filename, ".dpkg-old") ||
1804 endswith(filename, ".dpkg-new") ||
1805 endswith(filename, ".swp");
1808 int fd_nonblock(int fd, bool nonblock) {
1813 if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
1817 flags |= O_NONBLOCK;
1819 flags &= ~O_NONBLOCK;
1821 if (fcntl(fd, F_SETFL, flags) < 0)
1827 int fd_cloexec(int fd, bool cloexec) {
1832 if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
1836 flags |= FD_CLOEXEC;
1838 flags &= ~FD_CLOEXEC;
1840 if (fcntl(fd, F_SETFD, flags) < 0)
1846 static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
1849 assert(n_fdset == 0 || fdset);
1851 for (i = 0; i < n_fdset; i++)
1858 int close_all_fds(const int except[], unsigned n_except) {
1863 assert(n_except == 0 || except);
1865 d = opendir("/proc/self/fd");
1870 /* When /proc isn't available (for example in chroots)
1871 * the fallback is brute forcing through the fd
1874 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
1875 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
1877 if (fd_in_set(fd, except, n_except))
1880 if (close_nointr(fd) < 0)
1881 if (errno != EBADF && r == 0)
1888 while ((de = readdir(d))) {
1891 if (ignore_file(de->d_name))
1894 if (safe_atoi(de->d_name, &fd) < 0)
1895 /* Let's better ignore this, just in case */
1904 if (fd_in_set(fd, except, n_except))
1907 if (close_nointr(fd) < 0) {
1908 /* Valgrind has its own FD and doesn't want to have it closed */
1909 if (errno != EBADF && r == 0)
1918 bool chars_intersect(const char *a, const char *b) {
1921 /* Returns true if any of the chars in a are in b. */
1922 for (p = a; *p; p++)
1929 char *format_timestamp(char *buf, size_t l, usec_t t) {
1939 sec = (time_t) (t / USEC_PER_SEC);
1941 if (strftime(buf, l, "%a, %d %b %Y %H:%M:%S %z", localtime_r(&sec, &tm)) <= 0)
1947 char *format_timestamp_pretty(char *buf, size_t l, usec_t t) {
1950 n = now(CLOCK_REALTIME);
1952 if (t <= 0 || t > n || t + USEC_PER_DAY*7 <= t)
1957 if (d >= USEC_PER_YEAR)
1958 snprintf(buf, l, "%llu years and %llu months ago",
1959 (unsigned long long) (d / USEC_PER_YEAR),
1960 (unsigned long long) ((d % USEC_PER_YEAR) / USEC_PER_MONTH));
1961 else if (d >= USEC_PER_MONTH)
1962 snprintf(buf, l, "%llu months and %llu days ago",
1963 (unsigned long long) (d / USEC_PER_MONTH),
1964 (unsigned long long) ((d % USEC_PER_MONTH) / USEC_PER_DAY));
1965 else if (d >= USEC_PER_WEEK)
1966 snprintf(buf, l, "%llu weeks and %llu days ago",
1967 (unsigned long long) (d / USEC_PER_WEEK),
1968 (unsigned long long) ((d % USEC_PER_WEEK) / USEC_PER_DAY));
1969 else if (d >= 2*USEC_PER_DAY)
1970 snprintf(buf, l, "%llu days ago", (unsigned long long) (d / USEC_PER_DAY));
1971 else if (d >= 25*USEC_PER_HOUR)
1972 snprintf(buf, l, "1 day and %lluh ago",
1973 (unsigned long long) ((d - USEC_PER_DAY) / USEC_PER_HOUR));
1974 else if (d >= 6*USEC_PER_HOUR)
1975 snprintf(buf, l, "%lluh ago",
1976 (unsigned long long) (d / USEC_PER_HOUR));
1977 else if (d >= USEC_PER_HOUR)
1978 snprintf(buf, l, "%lluh %llumin ago",
1979 (unsigned long long) (d / USEC_PER_HOUR),
1980 (unsigned long long) ((d % USEC_PER_HOUR) / USEC_PER_MINUTE));
1981 else if (d >= 5*USEC_PER_MINUTE)
1982 snprintf(buf, l, "%llumin ago",
1983 (unsigned long long) (d / USEC_PER_MINUTE));
1984 else if (d >= USEC_PER_MINUTE)
1985 snprintf(buf, l, "%llumin %llus ago",
1986 (unsigned long long) (d / USEC_PER_MINUTE),
1987 (unsigned long long) ((d % USEC_PER_MINUTE) / USEC_PER_SEC));
1988 else if (d >= USEC_PER_SEC)
1989 snprintf(buf, l, "%llus ago",
1990 (unsigned long long) (d / USEC_PER_SEC));
1991 else if (d >= USEC_PER_MSEC)
1992 snprintf(buf, l, "%llums ago",
1993 (unsigned long long) (d / USEC_PER_MSEC));
1995 snprintf(buf, l, "%lluus ago",
1996 (unsigned long long) d);
1998 snprintf(buf, l, "now");
2004 char *format_timespan(char *buf, size_t l, usec_t t) {
2005 static const struct {
2009 { "w", USEC_PER_WEEK },
2010 { "d", USEC_PER_DAY },
2011 { "h", USEC_PER_HOUR },
2012 { "min", USEC_PER_MINUTE },
2013 { "s", USEC_PER_SEC },
2014 { "ms", USEC_PER_MSEC },
2024 if (t == (usec_t) -1)
2028 snprintf(p, l, "0");
2033 /* The result of this function can be parsed with parse_usec */
2035 for (i = 0; i < ELEMENTSOF(table); i++) {
2039 if (t < table[i].usec)
2045 k = snprintf(p, l, "%s%llu%s", p > buf ? " " : "", (unsigned long long) (t / table[i].usec), table[i].suffix);
2046 n = MIN((size_t) k, l);
2059 bool fstype_is_network(const char *fstype) {
2060 static const char * const table[] = {
2072 for (i = 0; i < ELEMENTSOF(table); i++)
2073 if (streq(table[i], fstype))
2082 if ((fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0)
2087 TIOCL_GETKMSGREDIRECT,
2091 if (ioctl(fd, TIOCLINUX, tiocl) < 0) {
2096 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
2099 if (ioctl(fd, VT_ACTIVATE, vt) < 0)
2103 close_nointr_nofail(fd);
2107 int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
2108 struct termios old_termios, new_termios;
2110 char line[LINE_MAX];
2115 if (tcgetattr(fileno(f), &old_termios) >= 0) {
2116 new_termios = old_termios;
2118 new_termios.c_lflag &= ~ICANON;
2119 new_termios.c_cc[VMIN] = 1;
2120 new_termios.c_cc[VTIME] = 0;
2122 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
2125 if (t != (usec_t) -1) {
2126 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
2127 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
2132 k = fread(&c, 1, 1, f);
2134 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
2140 *need_nl = c != '\n';
2147 if (t != (usec_t) -1)
2148 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
2151 if (!fgets(line, sizeof(line), f))
2156 if (strlen(line) != 1)
2166 int ask(char *ret, const char *replies, const char *text, ...) {
2173 on_tty = isatty(STDOUT_FILENO);
2179 bool need_nl = true;
2182 fputs(ANSI_HIGHLIGHT_ON, stdout);
2189 fputs(ANSI_HIGHLIGHT_OFF, stdout);
2193 r = read_one_char(stdin, &c, (usec_t) -1, &need_nl);
2196 if (r == -EBADMSG) {
2197 puts("Bad input, please try again.");
2208 if (strchr(replies, c)) {
2213 puts("Read unexpected character, please try again.");
2217 int reset_terminal_fd(int fd, bool switch_to_text) {
2218 struct termios termios;
2221 /* Set terminal to some sane defaults */
2225 /* We leave locked terminal attributes untouched, so that
2226 * Plymouth may set whatever it wants to set, and we don't
2227 * interfere with that. */
2229 /* Disable exclusive mode, just in case */
2230 ioctl(fd, TIOCNXCL);
2232 /* Switch to text mode */
2234 ioctl(fd, KDSETMODE, KD_TEXT);
2236 /* Enable console unicode mode */
2237 ioctl(fd, KDSKBMODE, K_UNICODE);
2239 if (tcgetattr(fd, &termios) < 0) {
2244 /* We only reset the stuff that matters to the software. How
2245 * hardware is set up we don't touch assuming that somebody
2246 * else will do that for us */
2248 termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
2249 termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
2250 termios.c_oflag |= ONLCR;
2251 termios.c_cflag |= CREAD;
2252 termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
2254 termios.c_cc[VINTR] = 03; /* ^C */
2255 termios.c_cc[VQUIT] = 034; /* ^\ */
2256 termios.c_cc[VERASE] = 0177;
2257 termios.c_cc[VKILL] = 025; /* ^X */
2258 termios.c_cc[VEOF] = 04; /* ^D */
2259 termios.c_cc[VSTART] = 021; /* ^Q */
2260 termios.c_cc[VSTOP] = 023; /* ^S */
2261 termios.c_cc[VSUSP] = 032; /* ^Z */
2262 termios.c_cc[VLNEXT] = 026; /* ^V */
2263 termios.c_cc[VWERASE] = 027; /* ^W */
2264 termios.c_cc[VREPRINT] = 022; /* ^R */
2265 termios.c_cc[VEOL] = 0;
2266 termios.c_cc[VEOL2] = 0;
2268 termios.c_cc[VTIME] = 0;
2269 termios.c_cc[VMIN] = 1;
2271 if (tcsetattr(fd, TCSANOW, &termios) < 0)
2275 /* Just in case, flush all crap out */
2276 tcflush(fd, TCIOFLUSH);
2281 int reset_terminal(const char *name) {
2284 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2288 r = reset_terminal_fd(fd, true);
2289 close_nointr_nofail(fd);
2294 int open_terminal(const char *name, int mode) {
2299 * If a TTY is in the process of being closed opening it might
2300 * cause EIO. This is horribly awful, but unlikely to be
2301 * changed in the kernel. Hence we work around this problem by
2302 * retrying a couple of times.
2304 * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
2308 fd = open(name, mode);
2315 /* Max 1s in total */
2319 usleep(50 * USEC_PER_MSEC);
2328 close_nointr_nofail(fd);
2333 close_nointr_nofail(fd);
2340 int flush_fd(int fd) {
2341 struct pollfd pollfd;
2345 pollfd.events = POLLIN;
2352 if ((r = poll(&pollfd, 1, 0)) < 0) {
2363 if ((l = read(fd, buf, sizeof(buf))) < 0) {
2368 if (errno == EAGAIN)
2379 int acquire_terminal(
2383 bool ignore_tiocstty_eperm,
2386 int fd = -1, notify = -1, r, wd = -1;
2391 /* We use inotify to be notified when the tty is closed. We
2392 * create the watch before checking if we can actually acquire
2393 * it, so that we don't lose any event.
2395 * Note: strictly speaking this actually watches for the
2396 * device being closed, it does *not* really watch whether a
2397 * tty loses its controlling process. However, unless some
2398 * rogue process uses TIOCNOTTY on /dev/tty *after* closing
2399 * its tty otherwise this will not become a problem. As long
2400 * as the administrator makes sure not configure any service
2401 * on the same tty as an untrusted user this should not be a
2402 * problem. (Which he probably should not do anyway.) */
2404 if (timeout != (usec_t) -1)
2405 ts = now(CLOCK_MONOTONIC);
2407 if (!fail && !force) {
2408 notify = inotify_init1(IN_CLOEXEC | (timeout != (usec_t) -1 ? IN_NONBLOCK : 0));
2414 wd = inotify_add_watch(notify, name, IN_CLOSE);
2423 r = flush_fd(notify);
2428 /* We pass here O_NOCTTY only so that we can check the return
2429 * value TIOCSCTTY and have a reliable way to figure out if we
2430 * successfully became the controlling process of the tty */
2431 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2435 /* First, try to get the tty */
2436 r = ioctl(fd, TIOCSCTTY, force);
2438 /* Sometimes it makes sense to ignore TIOCSCTTY
2439 * returning EPERM, i.e. when very likely we already
2440 * are have this controlling terminal. */
2441 if (r < 0 && errno == EPERM && ignore_tiocstty_eperm)
2444 if (r < 0 && (force || fail || errno != EPERM)) {
2454 assert(notify >= 0);
2457 uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
2459 struct inotify_event *e;
2461 if (timeout != (usec_t) -1) {
2464 n = now(CLOCK_MONOTONIC);
2465 if (ts + timeout < n) {
2470 r = fd_wait_for_event(fd, POLLIN, ts + timeout - n);
2480 l = read(notify, inotify_buffer, sizeof(inotify_buffer));
2483 if (errno == EINTR || errno == EAGAIN)
2490 e = (struct inotify_event*) inotify_buffer;
2495 if (e->wd != wd || !(e->mask & IN_CLOSE)) {
2500 step = sizeof(struct inotify_event) + e->len;
2501 assert(step <= (size_t) l);
2503 e = (struct inotify_event*) ((uint8_t*) e + step);
2510 /* We close the tty fd here since if the old session
2511 * ended our handle will be dead. It's important that
2512 * we do this after sleeping, so that we don't enter
2513 * an endless loop. */
2514 close_nointr_nofail(fd);
2518 close_nointr_nofail(notify);
2520 r = reset_terminal_fd(fd, true);
2522 log_warning("Failed to reset terminal: %s", strerror(-r));
2528 close_nointr_nofail(fd);
2531 close_nointr_nofail(notify);
2536 int release_terminal(void) {
2538 struct sigaction sa_old, sa_new;
2540 if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC)) < 0)
2543 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2544 * by our own TIOCNOTTY */
2547 sa_new.sa_handler = SIG_IGN;
2548 sa_new.sa_flags = SA_RESTART;
2549 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2551 if (ioctl(fd, TIOCNOTTY) < 0)
2554 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2556 close_nointr_nofail(fd);
2560 int sigaction_many(const struct sigaction *sa, ...) {
2565 while ((sig = va_arg(ap, int)) > 0)
2566 if (sigaction(sig, sa, NULL) < 0)
2573 int ignore_signals(int sig, ...) {
2574 struct sigaction sa;
2579 sa.sa_handler = SIG_IGN;
2580 sa.sa_flags = SA_RESTART;
2582 if (sigaction(sig, &sa, NULL) < 0)
2586 while ((sig = va_arg(ap, int)) > 0)
2587 if (sigaction(sig, &sa, NULL) < 0)
2594 int default_signals(int sig, ...) {
2595 struct sigaction sa;
2600 sa.sa_handler = SIG_DFL;
2601 sa.sa_flags = SA_RESTART;
2603 if (sigaction(sig, &sa, NULL) < 0)
2607 while ((sig = va_arg(ap, int)) > 0)
2608 if (sigaction(sig, &sa, NULL) < 0)
2615 int close_pipe(int p[]) {
2621 a = close_nointr(p[0]);
2626 b = close_nointr(p[1]);
2630 return a < 0 ? a : b;
2633 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2642 while (nbytes > 0) {
2645 if ((k = read(fd, p, nbytes)) <= 0) {
2647 if (k < 0 && errno == EINTR)
2650 if (k < 0 && errno == EAGAIN && do_poll) {
2651 struct pollfd pollfd;
2655 pollfd.events = POLLIN;
2657 if (poll(&pollfd, 1, -1) < 0) {
2661 return n > 0 ? n : -errno;
2664 if (pollfd.revents != POLLIN)
2665 return n > 0 ? n : -EIO;
2670 return n > 0 ? n : (k < 0 ? -errno : 0);
2681 ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2690 while (nbytes > 0) {
2693 k = write(fd, p, nbytes);
2696 if (k < 0 && errno == EINTR)
2699 if (k < 0 && errno == EAGAIN && do_poll) {
2700 struct pollfd pollfd;
2704 pollfd.events = POLLOUT;
2706 if (poll(&pollfd, 1, -1) < 0) {
2710 return n > 0 ? n : -errno;
2713 if (pollfd.revents != POLLOUT)
2714 return n > 0 ? n : -EIO;
2719 return n > 0 ? n : (k < 0 ? -errno : 0);
2730 int parse_usec(const char *t, usec_t *usec) {
2731 static const struct {
2735 { "sec", USEC_PER_SEC },
2736 { "s", USEC_PER_SEC },
2737 { "min", USEC_PER_MINUTE },
2738 { "hr", USEC_PER_HOUR },
2739 { "h", USEC_PER_HOUR },
2740 { "d", USEC_PER_DAY },
2741 { "w", USEC_PER_WEEK },
2742 { "msec", USEC_PER_MSEC },
2743 { "ms", USEC_PER_MSEC },
2744 { "m", USEC_PER_MINUTE },
2747 { "", USEC_PER_SEC }, /* default is sec */
2763 l = strtoll(p, &e, 10);
2774 e += strspn(e, WHITESPACE);
2776 for (i = 0; i < ELEMENTSOF(table); i++)
2777 if (startswith(e, table[i].suffix)) {
2778 r += (usec_t) l * table[i].usec;
2779 p = e + strlen(table[i].suffix);
2783 if (i >= ELEMENTSOF(table))
2793 int parse_nsec(const char *t, nsec_t *nsec) {
2794 static const struct {
2798 { "sec", NSEC_PER_SEC },
2799 { "s", NSEC_PER_SEC },
2800 { "min", NSEC_PER_MINUTE },
2801 { "hr", NSEC_PER_HOUR },
2802 { "h", NSEC_PER_HOUR },
2803 { "d", NSEC_PER_DAY },
2804 { "w", NSEC_PER_WEEK },
2805 { "msec", NSEC_PER_MSEC },
2806 { "ms", NSEC_PER_MSEC },
2807 { "m", NSEC_PER_MINUTE },
2808 { "usec", NSEC_PER_USEC },
2809 { "us", NSEC_PER_USEC },
2812 { "", 1ULL }, /* default is nsec */
2828 l = strtoll(p, &e, 10);
2839 e += strspn(e, WHITESPACE);
2841 for (i = 0; i < ELEMENTSOF(table); i++)
2842 if (startswith(e, table[i].suffix)) {
2843 r += (nsec_t) l * table[i].nsec;
2844 p = e + strlen(table[i].suffix);
2848 if (i >= ELEMENTSOF(table))
2858 int parse_bytes(const char *t, off_t *bytes) {
2859 static const struct {
2865 { "M", 1024ULL*1024ULL },
2866 { "G", 1024ULL*1024ULL*1024ULL },
2867 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2868 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2869 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2886 l = strtoll(p, &e, 10);
2897 e += strspn(e, WHITESPACE);
2899 for (i = 0; i < ELEMENTSOF(table); i++)
2900 if (startswith(e, table[i].suffix)) {
2901 r += (off_t) l * table[i].factor;
2902 p = e + strlen(table[i].suffix);
2906 if (i >= ELEMENTSOF(table))
2916 int make_stdio(int fd) {
2921 r = dup2(fd, STDIN_FILENO);
2922 s = dup2(fd, STDOUT_FILENO);
2923 t = dup2(fd, STDERR_FILENO);
2926 close_nointr_nofail(fd);
2928 if (r < 0 || s < 0 || t < 0)
2931 fd_cloexec(STDIN_FILENO, false);
2932 fd_cloexec(STDOUT_FILENO, false);
2933 fd_cloexec(STDERR_FILENO, false);
2938 int make_null_stdio(void) {
2941 if ((null_fd = open("/dev/null", O_RDWR|O_NOCTTY)) < 0)
2944 return make_stdio(null_fd);
2947 bool is_device_path(const char *path) {
2949 /* Returns true on paths that refer to a device, either in
2950 * sysfs or in /dev */
2953 path_startswith(path, "/dev/") ||
2954 path_startswith(path, "/sys/");
2957 int dir_is_empty(const char *path) {
2960 struct dirent buf, *de;
2962 if (!(d = opendir(path)))
2966 if ((r = readdir_r(d, &buf, &de)) > 0) {
2976 if (!ignore_file(de->d_name)) {
2986 unsigned long long random_ull(void) {
2991 if ((fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0)
2994 r = loop_read(fd, &ull, sizeof(ull), true);
2995 close_nointr_nofail(fd);
2997 if (r != sizeof(ull))
3003 return random() * RAND_MAX + random();
3006 void rename_process(const char name[8]) {
3009 /* This is a like a poor man's setproctitle(). It changes the
3010 * comm field, argv[0], and also the glibc's internally used
3011 * name of the process. For the first one a limit of 16 chars
3012 * applies, to the second one usually one of 10 (i.e. length
3013 * of "/sbin/init"), to the third one one of 7 (i.e. length of
3014 * "systemd"). If you pass a longer string it will be
3017 prctl(PR_SET_NAME, name);
3019 if (program_invocation_name)
3020 strncpy(program_invocation_name, name, strlen(program_invocation_name));
3022 if (saved_argc > 0) {
3026 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
3028 for (i = 1; i < saved_argc; i++) {
3032 memset(saved_argv[i], 0, strlen(saved_argv[i]));
3037 void sigset_add_many(sigset_t *ss, ...) {
3044 while ((sig = va_arg(ap, int)) > 0)
3045 assert_se(sigaddset(ss, sig) == 0);
3049 char* gethostname_malloc(void) {
3052 assert_se(uname(&u) >= 0);
3054 if (!isempty(u.nodename) && !streq(u.nodename, "(none)"))
3055 return strdup(u.nodename);
3057 return strdup(u.sysname);
3060 bool hostname_is_set(void) {
3063 assert_se(uname(&u) >= 0);
3065 return !isempty(u.nodename) && !streq(u.nodename, "(none)");
3068 char* getlogname_malloc(void) {
3072 struct passwd pwbuf, *pw = NULL;
3075 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
3080 /* Shortcut things to avoid NSS lookups */
3082 return strdup("root");
3084 if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) <= 0)
3087 if (!(buf = malloc(bufsize)))
3090 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw) {
3091 name = strdup(pw->pw_name);
3098 if (asprintf(&name, "%lu", (unsigned long) uid) < 0)
3104 int getttyname_malloc(int fd, char **r) {
3105 char path[PATH_MAX], *c;
3110 if ((k = ttyname_r(fd, path, sizeof(path))) != 0)
3115 if (!(c = strdup(startswith(path, "/dev/") ? path + 5 : path)))
3122 int getttyname_harder(int fd, char **r) {
3126 if ((k = getttyname_malloc(fd, &s)) < 0)
3129 if (streq(s, "tty")) {
3131 return get_ctty(0, NULL, r);
3138 int get_ctty_devnr(pid_t pid, dev_t *d) {
3140 char line[LINE_MAX], *p, *fn;
3141 unsigned long ttynr;
3144 if (asprintf(&fn, "/proc/%lu/stat", (unsigned long) (pid <= 0 ? getpid() : pid)) < 0)
3147 f = fopen(fn, "re");
3152 if (!fgets(line, sizeof(line), f)) {
3153 k = feof(f) ? -EIO : -errno;
3160 p = strrchr(line, ')');
3170 "%*d " /* session */
3179 int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
3181 char fn[PATH_MAX], *s, *b, *p;
3186 k = get_ctty_devnr(pid, &devnr);
3190 snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
3193 if ((k = readlink_malloc(fn, &s)) < 0) {
3198 /* This is an ugly hack */
3199 if (major(devnr) == 136) {
3200 if (asprintf(&b, "pts/%lu", (unsigned long) minor(devnr)) < 0)
3210 /* Probably something like the ptys which have no
3211 * symlink in /dev/char. Let's return something
3212 * vaguely useful. */
3214 if (!(b = strdup(fn + 5)))
3224 if (startswith(s, "/dev/"))
3226 else if (startswith(s, "../"))
3244 int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
3250 /* This returns the first error we run into, but nevertheless
3251 * tries to go on. This closes the passed fd. */
3255 close_nointr_nofail(fd);
3257 return errno == ENOENT ? 0 : -errno;
3261 struct dirent buf, *de;
3262 bool is_dir, keep_around;
3266 r = readdir_r(d, &buf, &de);
3267 if (r != 0 && ret == 0) {
3275 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
3278 if (de->d_type == DT_UNKNOWN ||
3280 (de->d_type == DT_DIR && root_dev)) {
3281 if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
3282 if (ret == 0 && errno != ENOENT)
3287 is_dir = S_ISDIR(st.st_mode);
3290 (st.st_uid == 0 || st.st_uid == getuid()) &&
3291 (st.st_mode & S_ISVTX);
3293 is_dir = de->d_type == DT_DIR;
3294 keep_around = false;
3300 /* if root_dev is set, remove subdirectories only, if device is same as dir */
3301 if (root_dev && st.st_dev != root_dev->st_dev)
3304 subdir_fd = openat(fd, de->d_name,
3305 O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3306 if (subdir_fd < 0) {
3307 if (ret == 0 && errno != ENOENT)
3312 r = rm_rf_children(subdir_fd, only_dirs, honour_sticky, root_dev);
3313 if (r < 0 && ret == 0)
3317 if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
3318 if (ret == 0 && errno != ENOENT)
3322 } else if (!only_dirs && !keep_around) {
3324 if (unlinkat(fd, de->d_name, 0) < 0) {
3325 if (ret == 0 && errno != ENOENT)
3336 int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3343 assert(!streq(path, "/"));
3345 fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3348 if (errno != ENOTDIR)
3351 if (delete_root && !only_dirs)
3352 if (unlink(path) < 0 && errno != ENOENT)
3358 r = rm_rf_children(fd, only_dirs, honour_sticky, NULL);
3362 if (honour_sticky && file_is_priv_sticky(path) > 0)
3365 if (rmdir(path) < 0 && errno != ENOENT) {
3374 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
3377 /* Under the assumption that we are running privileged we
3378 * first change the access mode and only then hand out
3379 * ownership to avoid a window where access is too open. */
3381 if (mode != (mode_t) -1)
3382 if (chmod(path, mode) < 0)
3385 if (uid != (uid_t) -1 || gid != (gid_t) -1)
3386 if (chown(path, uid, gid) < 0)
3392 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
3395 /* Under the assumption that we are running privileged we
3396 * first change the access mode and only then hand out
3397 * ownership to avoid a window where access is too open. */
3399 if (fchmod(fd, mode) < 0)
3402 if (fchown(fd, uid, gid) < 0)
3408 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
3412 /* Allocates the cpuset in the right size */
3415 if (!(r = CPU_ALLOC(n)))
3418 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
3419 CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
3429 if (errno != EINVAL)
3436 void status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) {
3438 static const char status_indent[] = " "; /* "[" STATUS "] " */
3440 struct iovec iovec[5];
3445 /* This is independent of logging, as status messages are
3446 * optional and go exclusively to the console. */
3448 if (vasprintf(&s, format, ap) < 0)
3451 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
3464 sl = status ? strlen(status_indent) : 0;
3470 e = ellipsize(s, emax, 75);
3480 if (!isempty(status)) {
3481 IOVEC_SET_STRING(iovec[n++], "[");
3482 IOVEC_SET_STRING(iovec[n++], status);
3483 IOVEC_SET_STRING(iovec[n++], "] ");
3485 IOVEC_SET_STRING(iovec[n++], status_indent);
3488 IOVEC_SET_STRING(iovec[n++], s);
3489 IOVEC_SET_STRING(iovec[n++], "\n");
3491 writev(fd, iovec, n);
3497 close_nointr_nofail(fd);
3500 void status_printf(const char *status, bool ellipse, const char *format, ...) {
3505 va_start(ap, format);
3506 status_vprintf(status, ellipse, format, ap);
3510 void status_welcome(void) {
3511 char *pretty_name = NULL, *ansi_color = NULL;
3512 const char *const_pretty = NULL, *const_color = NULL;
3515 if ((r = parse_env_file("/etc/os-release", NEWLINE,
3516 "PRETTY_NAME", &pretty_name,
3517 "ANSI_COLOR", &ansi_color,
3521 log_warning("Failed to read /etc/os-release: %s", strerror(-r));
3524 if (!pretty_name && !const_pretty)
3525 const_pretty = "Linux";
3527 if (!ansi_color && !const_color)
3532 "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
3533 const_color ? const_color : ansi_color,
3534 const_pretty ? const_pretty : pretty_name);
3540 char *replace_env(const char *format, char **env) {
3547 const char *e, *word = format;
3552 for (e = format; *e; e ++) {
3563 if (!(k = strnappend(r, word, e-word-1)))
3572 } else if (*e == '$') {
3573 if (!(k = strnappend(r, word, e-word)))
3589 if (!(t = strv_env_get_with_length(env, word+2, e-word-2)))
3592 if (!(k = strappend(r, t)))
3605 if (!(k = strnappend(r, word, e-word)))
3616 char **replace_env_argv(char **argv, char **env) {
3618 unsigned k = 0, l = 0;
3620 l = strv_length(argv);
3622 if (!(r = new(char*, l+1)))
3625 STRV_FOREACH(i, argv) {
3627 /* If $FOO appears as single word, replace it by the split up variable */
3628 if ((*i)[0] == '$' && (*i)[1] != '{') {
3633 if ((e = strv_env_get(env, *i+1))) {
3635 if (!(m = strv_split_quoted(e))) {
3646 if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
3655 memcpy(r + k, m, q * sizeof(char*));
3663 /* If ${FOO} appears as part of a word, replace it by the variable as-is */
3664 if (!(r[k++] = replace_env(*i, env))) {
3674 int fd_columns(int fd) {
3678 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3687 unsigned columns(void) {
3688 static __thread int parsed_columns = 0;
3691 if (_likely_(parsed_columns > 0))
3692 return parsed_columns;
3694 e = getenv("COLUMNS");
3696 parsed_columns = atoi(e);
3698 if (parsed_columns <= 0)
3699 parsed_columns = fd_columns(STDOUT_FILENO);
3701 if (parsed_columns <= 0)
3702 parsed_columns = 80;
3704 return parsed_columns;
3707 int fd_lines(int fd) {
3711 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3720 unsigned lines(void) {
3721 static __thread int parsed_lines = 0;
3724 if (_likely_(parsed_lines > 0))
3725 return parsed_lines;
3727 e = getenv("LINES");
3729 parsed_lines = atoi(e);
3731 if (parsed_lines <= 0)
3732 parsed_lines = fd_lines(STDOUT_FILENO);
3734 if (parsed_lines <= 0)
3737 return parsed_lines;
3740 int running_in_chroot(void) {
3746 /* Only works as root */
3748 if (stat("/proc/1/root", &a) < 0)
3751 if (stat("/", &b) < 0)
3755 a.st_dev != b.st_dev ||
3756 a.st_ino != b.st_ino;
3759 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
3764 assert(percent <= 100);
3765 assert(new_length >= 3);
3767 if (old_length <= 3 || old_length <= new_length)
3768 return strndup(s, old_length);
3770 r = new0(char, new_length+1);
3774 x = (new_length * percent) / 100;
3776 if (x > new_length - 3)
3784 s + old_length - (new_length - x - 3),
3785 new_length - x - 3);
3790 char *ellipsize(const char *s, size_t length, unsigned percent) {
3791 return ellipsize_mem(s, strlen(s), length, percent);
3794 int touch(const char *path) {
3799 if ((fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644)) < 0)
3802 close_nointr_nofail(fd);
3806 char *unquote(const char *s, const char* quotes) {
3814 if (strchr(quotes, s[0]) && s[l-1] == s[0])
3815 return strndup(s+1, l-2);
3820 char *normalize_env_assignment(const char *s) {
3821 char *name, *value, *p, *r;
3826 if (!(r = strdup(s)))
3832 if (!(name = strndup(s, p - s)))
3835 if (!(p = strdup(p+1))) {
3840 value = unquote(strstrip(p), QUOTES);
3848 if (asprintf(&r, "%s=%s", name, value) < 0)
3857 int wait_for_terminate(pid_t pid, siginfo_t *status) {
3868 if (waitid(P_PID, pid, status, WEXITED) < 0) {
3880 int wait_for_terminate_and_warn(const char *name, pid_t pid) {
3887 if ((r = wait_for_terminate(pid, &status)) < 0) {
3888 log_warning("Failed to wait for %s: %s", name, strerror(-r));
3892 if (status.si_code == CLD_EXITED) {
3893 if (status.si_status != 0) {
3894 log_warning("%s failed with error code %i.", name, status.si_status);
3895 return status.si_status;
3898 log_debug("%s succeeded.", name);
3901 } else if (status.si_code == CLD_KILLED ||
3902 status.si_code == CLD_DUMPED) {
3904 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
3908 log_warning("%s failed due to unknown reason.", name);
3913 _noreturn_ void freeze(void) {
3915 /* Make sure nobody waits for us on a socket anymore */
3916 close_all_fds(NULL, 0);
3924 bool null_or_empty(struct stat *st) {
3927 if (S_ISREG(st->st_mode) && st->st_size <= 0)
3930 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
3936 int null_or_empty_path(const char *fn) {
3941 if (stat(fn, &st) < 0)
3944 return null_or_empty(&st);
3947 DIR *xopendirat(int fd, const char *name, int flags) {
3951 if ((nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags)) < 0)
3954 if (!(d = fdopendir(nfd))) {
3955 close_nointr_nofail(nfd);
3962 int signal_from_string_try_harder(const char *s) {
3966 if ((signo = signal_from_string(s)) <= 0)
3967 if (startswith(s, "SIG"))
3968 return signal_from_string(s+3);
3973 void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) {
3979 if (!dual_timestamp_is_set(t))
3982 fprintf(f, "%s=%llu %llu\n",
3984 (unsigned long long) t->realtime,
3985 (unsigned long long) t->monotonic);
3988 void dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
3989 unsigned long long a, b;
3994 if (sscanf(value, "%lli %llu", &a, &b) != 2)
3995 log_debug("Failed to parse finish timestamp value %s", value);
4002 char *fstab_node_to_udev_node(const char *p) {
4006 /* FIXME: to follow udev's logic 100% we need to leave valid
4007 * UTF8 chars unescaped */
4009 if (startswith(p, "LABEL=")) {
4011 if (!(u = unquote(p+6, "\"\'")))
4014 t = xescape(u, "/ ");
4020 r = asprintf(&dn, "/dev/disk/by-label/%s", t);
4029 if (startswith(p, "UUID=")) {
4031 if (!(u = unquote(p+5, "\"\'")))
4034 t = xescape(u, "/ ");
4040 r = asprintf(&dn, "/dev/disk/by-uuid/%s", t);
4052 bool tty_is_vc(const char *tty) {
4055 if (startswith(tty, "/dev/"))
4058 return vtnr_from_tty(tty) >= 0;
4061 bool tty_is_console(const char *tty) {
4064 if (startswith(tty, "/dev/"))
4067 return streq(tty, "console");
4070 int vtnr_from_tty(const char *tty) {
4075 if (startswith(tty, "/dev/"))
4078 if (!startswith(tty, "tty") )
4081 if (tty[3] < '0' || tty[3] > '9')
4084 r = safe_atoi(tty+3, &i);
4088 if (i < 0 || i > 63)
4094 bool tty_is_vc_resolve(const char *tty) {
4095 char *active = NULL;
4100 if (startswith(tty, "/dev/"))
4103 /* Resolve where /dev/console is pointing to, if /sys is
4104 * actually ours (i.e. not read-only-mounted which is a sign
4105 * for container setups) */
4106 if (streq(tty, "console") && path_is_read_only_fs("/sys") <= 0)
4107 if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) {
4108 /* If multiple log outputs are configured the
4109 * last one is what /dev/console points to */
4110 tty = strrchr(active, ' ');
4123 const char *default_term_for_tty(const char *tty) {
4126 return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102";
4129 bool dirent_is_file(const struct dirent *de) {
4132 if (ignore_file(de->d_name))
4135 if (de->d_type != DT_REG &&
4136 de->d_type != DT_LNK &&
4137 de->d_type != DT_UNKNOWN)
4143 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
4146 if (!dirent_is_file(de))
4149 return endswith(de->d_name, suffix);
4152 void execute_directory(const char *directory, DIR *d, char *argv[]) {
4155 Hashmap *pids = NULL;
4159 /* Executes all binaries in a directory in parallel and waits
4160 * until all they all finished. */
4163 if (!(_d = opendir(directory))) {
4165 if (errno == ENOENT)
4168 log_error("Failed to enumerate directory %s: %m", directory);
4175 if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) {
4176 log_error("Failed to allocate set.");
4180 while ((de = readdir(d))) {
4185 if (!dirent_is_file(de))
4188 if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
4189 log_error("Out of memory");
4193 if ((pid = fork()) < 0) {
4194 log_error("Failed to fork: %m");
4212 log_error("Failed to execute %s: %m", path);
4213 _exit(EXIT_FAILURE);
4216 log_debug("Spawned %s as %lu", path, (unsigned long) pid);
4218 if ((k = hashmap_put(pids, UINT_TO_PTR(pid), path)) < 0) {
4219 log_error("Failed to add PID to set: %s", strerror(-k));
4224 while (!hashmap_isempty(pids)) {
4225 pid_t pid = PTR_TO_UINT(hashmap_first_key(pids));
4230 if (waitid(P_PID, pid, &si, WEXITED) < 0) {
4235 log_error("waitid() failed: %m");
4239 if ((path = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) {
4240 if (!is_clean_exit(si.si_code, si.si_status)) {
4241 if (si.si_code == CLD_EXITED)
4242 log_error("%s exited with exit status %i.", path, si.si_status);
4244 log_error("%s terminated by signal %s.", path, signal_to_string(si.si_status));
4246 log_debug("%s exited successfully.", path);
4257 hashmap_free_free(pids);
4260 int kill_and_sigcont(pid_t pid, int sig) {
4263 r = kill(pid, sig) < 0 ? -errno : 0;
4271 bool nulstr_contains(const char*nulstr, const char *needle) {
4277 NULSTR_FOREACH(i, nulstr)
4278 if (streq(i, needle))
4284 bool plymouth_running(void) {
4285 return access("/run/plymouth/pid", F_OK) >= 0;
4288 void parse_syslog_priority(char **p, int *priority) {
4289 int a = 0, b = 0, c = 0;
4299 if (!strchr(*p, '>'))
4302 if ((*p)[2] == '>') {
4303 c = undecchar((*p)[1]);
4305 } else if ((*p)[3] == '>') {
4306 b = undecchar((*p)[1]);
4307 c = undecchar((*p)[2]);
4309 } else if ((*p)[4] == '>') {
4310 a = undecchar((*p)[1]);
4311 b = undecchar((*p)[2]);
4312 c = undecchar((*p)[3]);
4317 if (a < 0 || b < 0 || c < 0)
4320 *priority = a*100+b*10+c;
4324 void skip_syslog_pid(char **buf) {
4336 p += strspn(p, "0123456789");
4346 void skip_syslog_date(char **buf) {
4354 LETTER, LETTER, LETTER,
4356 SPACE_OR_NUMBER, NUMBER,
4358 SPACE_OR_NUMBER, NUMBER,
4360 SPACE_OR_NUMBER, NUMBER,
4362 SPACE_OR_NUMBER, NUMBER,
4374 for (i = 0; i < ELEMENTSOF(sequence); i++, p++) {
4379 switch (sequence[i]) {
4386 case SPACE_OR_NUMBER:
4393 if (*p < '0' || *p > '9')
4399 if (!(*p >= 'A' && *p <= 'Z') &&
4400 !(*p >= 'a' && *p <= 'z'))
4416 char* strshorten(char *s, size_t l) {
4425 static bool hostname_valid_char(char c) {
4427 (c >= 'a' && c <= 'z') ||
4428 (c >= 'A' && c <= 'Z') ||
4429 (c >= '0' && c <= '9') ||
4435 bool hostname_is_valid(const char *s) {
4441 for (p = s; *p; p++)
4442 if (!hostname_valid_char(*p))
4445 if (p-s > HOST_NAME_MAX)
4451 char* hostname_cleanup(char *s) {
4454 for (p = s, d = s; *p; p++)
4455 if ((*p >= 'a' && *p <= 'z') ||
4456 (*p >= 'A' && *p <= 'Z') ||
4457 (*p >= '0' && *p <= '9') ||
4465 strshorten(s, HOST_NAME_MAX);
4469 int pipe_eof(int fd) {
4470 struct pollfd pollfd;
4475 pollfd.events = POLLIN|POLLHUP;
4477 r = poll(&pollfd, 1, 0);
4484 return pollfd.revents & POLLHUP;
4487 int fd_wait_for_event(int fd, int event, usec_t t) {
4488 struct pollfd pollfd;
4493 pollfd.events = event;
4495 r = poll(&pollfd, 1, t == (usec_t) -1 ? -1 : (int) (t / USEC_PER_MSEC));
4502 return pollfd.revents;
4505 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
4516 t = new(char, strlen(path) + 1 + 6 + 1);
4520 fn = path_get_file_name(path);
4524 stpcpy(stpcpy(t+k+1, fn), "XXXXXX");
4526 fd = mkostemp(t, O_WRONLY|O_CLOEXEC);
4532 f = fdopen(fd, "we");
4545 int terminal_vhangup_fd(int fd) {
4548 if (ioctl(fd, TIOCVHANGUP) < 0)
4554 int terminal_vhangup(const char *name) {
4557 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4561 r = terminal_vhangup_fd(fd);
4562 close_nointr_nofail(fd);
4567 int vt_disallocate(const char *name) {
4571 /* Deallocate the VT if possible. If not possible
4572 * (i.e. because it is the active one), at least clear it
4573 * entirely (including the scrollback buffer) */
4575 if (!startswith(name, "/dev/"))
4578 if (!tty_is_vc(name)) {
4579 /* So this is not a VT. I guess we cannot deallocate
4580 * it then. But let's at least clear the screen */
4582 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4587 "\033[r" /* clear scrolling region */
4588 "\033[H" /* move home */
4589 "\033[2J", /* clear screen */
4591 close_nointr_nofail(fd);
4596 if (!startswith(name, "/dev/tty"))
4599 r = safe_atou(name+8, &u);
4606 /* Try to deallocate */
4607 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
4611 r = ioctl(fd, VT_DISALLOCATE, u);
4612 close_nointr_nofail(fd);
4620 /* Couldn't deallocate, so let's clear it fully with
4622 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4627 "\033[r" /* clear scrolling region */
4628 "\033[H" /* move home */
4629 "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
4631 close_nointr_nofail(fd);
4636 int copy_file(const char *from, const char *to) {
4642 fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
4646 fdt = open(to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY, 0644);
4648 close_nointr_nofail(fdf);
4656 n = read(fdf, buf, sizeof(buf));
4660 close_nointr_nofail(fdf);
4671 k = loop_write(fdt, buf, n, false);
4673 r = k < 0 ? k : (errno ? -errno : -EIO);
4675 close_nointr_nofail(fdf);
4683 close_nointr_nofail(fdf);
4684 r = close_nointr(fdt);
4694 int symlink_or_copy(const char *from, const char *to) {
4695 char *pf = NULL, *pt = NULL;
4702 if (path_get_parent(from, &pf) < 0 ||
4703 path_get_parent(to, &pt) < 0) {
4708 if (stat(pf, &a) < 0 ||
4714 if (a.st_dev != b.st_dev) {
4718 return copy_file(from, to);
4721 if (symlink(from, to) < 0) {
4735 int symlink_or_copy_atomic(const char *from, const char *to) {
4739 unsigned long long ull;
4746 t = new(char, strlen(to) + 1 + 16 + 1);
4750 fn = path_get_file_name(to);
4754 x = stpcpy(t+k+1, fn);
4757 for (i = 0; i < 16; i++) {
4758 *(x++) = hexchar(ull & 0xF);
4764 r = symlink_or_copy(from, t);
4771 if (rename(t, to) < 0) {
4782 bool display_is_local(const char *display) {
4786 display[0] == ':' &&
4787 display[1] >= '0' &&
4791 int socket_from_display(const char *display, char **path) {
4798 if (!display_is_local(display))
4801 k = strspn(display+1, "0123456789");
4803 f = new(char, sizeof("/tmp/.X11-unix/X") + k);
4807 c = stpcpy(f, "/tmp/.X11-unix/X");
4808 memcpy(c, display+1, k);
4816 int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home) {
4823 /* We enforce some special rules for uid=0: in order to avoid
4824 * NSS lookups for root we hardcode its data. */
4826 if (streq(*username, "root") || streq(*username, "0")) {
4840 if (parse_uid(*username, &u) >= 0) {
4844 /* If there are multiple users with the same id, make
4845 * sure to leave $USER to the configured value instead
4846 * of the first occurrence in the database. However if
4847 * the uid was configured by a numeric uid, then let's
4848 * pick the real username from /etc/passwd. */
4850 *username = p->pw_name;
4853 p = getpwnam(*username);
4857 return errno != 0 ? -errno : -ESRCH;
4871 int get_group_creds(const char **groupname, gid_t *gid) {
4877 /* We enforce some special rules for gid=0: in order to avoid
4878 * NSS lookups for root we hardcode its data. */
4880 if (streq(*groupname, "root") || streq(*groupname, "0")) {
4881 *groupname = "root";
4889 if (parse_gid(*groupname, &id) >= 0) {
4894 *groupname = g->gr_name;
4897 g = getgrnam(*groupname);
4901 return errno != 0 ? -errno : -ESRCH;
4909 int in_group(const char *name) {
4911 int ngroups_max, r, i;
4913 r = get_group_creds(&name, &gid);
4917 if (getgid() == gid)
4920 if (getegid() == gid)
4923 ngroups_max = sysconf(_SC_NGROUPS_MAX);
4924 assert(ngroups_max > 0);
4926 gids = alloca(sizeof(gid_t) * ngroups_max);
4928 r = getgroups(ngroups_max, gids);
4932 for (i = 0; i < r; i++)
4939 int glob_exists(const char *path) {
4947 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
4949 if (k == GLOB_NOMATCH)
4951 else if (k == GLOB_NOSPACE)
4954 r = !strv_isempty(g.gl_pathv);
4956 r = errno ? -errno : -EIO;
4963 int dirent_ensure_type(DIR *d, struct dirent *de) {
4969 if (de->d_type != DT_UNKNOWN)
4972 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
4976 S_ISREG(st.st_mode) ? DT_REG :
4977 S_ISDIR(st.st_mode) ? DT_DIR :
4978 S_ISLNK(st.st_mode) ? DT_LNK :
4979 S_ISFIFO(st.st_mode) ? DT_FIFO :
4980 S_ISSOCK(st.st_mode) ? DT_SOCK :
4981 S_ISCHR(st.st_mode) ? DT_CHR :
4982 S_ISBLK(st.st_mode) ? DT_BLK :
4988 int in_search_path(const char *path, char **search) {
4992 r = path_get_parent(path, &parent);
4998 STRV_FOREACH(i, search) {
4999 if (path_equal(parent, *i)) {
5010 int get_files_in_directory(const char *path, char ***list) {
5018 /* Returns all files in a directory in *list, and the number
5019 * of files as return value. If list is NULL returns only the
5027 struct dirent buffer, *de;
5030 k = readdir_r(d, &buffer, &de);
5039 dirent_ensure_type(d, de);
5041 if (!dirent_is_file(de))
5045 if ((unsigned) r >= n) {
5049 t = realloc(l, sizeof(char*) * n);
5058 assert((unsigned) r < n);
5060 l[r] = strdup(de->d_name);
5084 char *join(const char *x, ...) {
5097 t = va_arg(ap, const char *);
5120 t = va_arg(ap, const char *);
5134 bool is_main_thread(void) {
5135 static __thread int cached = 0;
5137 if (_unlikely_(cached == 0))
5138 cached = getpid() == gettid() ? 1 : -1;
5143 int block_get_whole_disk(dev_t d, dev_t *ret) {
5150 /* If it has a queue this is good enough for us */
5151 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
5154 r = access(p, F_OK);
5162 /* If it is a partition find the originating device */
5163 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
5166 r = access(p, F_OK);
5172 /* Get parent dev_t */
5173 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
5176 r = read_one_line_file(p, &s);
5182 r = sscanf(s, "%u:%u", &m, &n);
5188 /* Only return this if it is really good enough for us. */
5189 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
5192 r = access(p, F_OK);
5196 *ret = makedev(m, n);
5203 int file_is_priv_sticky(const char *p) {
5208 if (lstat(p, &st) < 0)
5212 (st.st_uid == 0 || st.st_uid == getuid()) &&
5213 (st.st_mode & S_ISVTX);
5216 static const char *const ioprio_class_table[] = {
5217 [IOPRIO_CLASS_NONE] = "none",
5218 [IOPRIO_CLASS_RT] = "realtime",
5219 [IOPRIO_CLASS_BE] = "best-effort",
5220 [IOPRIO_CLASS_IDLE] = "idle"
5223 DEFINE_STRING_TABLE_LOOKUP(ioprio_class, int);
5225 static const char *const sigchld_code_table[] = {
5226 [CLD_EXITED] = "exited",
5227 [CLD_KILLED] = "killed",
5228 [CLD_DUMPED] = "dumped",
5229 [CLD_TRAPPED] = "trapped",
5230 [CLD_STOPPED] = "stopped",
5231 [CLD_CONTINUED] = "continued",
5234 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
5236 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
5237 [LOG_FAC(LOG_KERN)] = "kern",
5238 [LOG_FAC(LOG_USER)] = "user",
5239 [LOG_FAC(LOG_MAIL)] = "mail",
5240 [LOG_FAC(LOG_DAEMON)] = "daemon",
5241 [LOG_FAC(LOG_AUTH)] = "auth",
5242 [LOG_FAC(LOG_SYSLOG)] = "syslog",
5243 [LOG_FAC(LOG_LPR)] = "lpr",
5244 [LOG_FAC(LOG_NEWS)] = "news",
5245 [LOG_FAC(LOG_UUCP)] = "uucp",
5246 [LOG_FAC(LOG_CRON)] = "cron",
5247 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
5248 [LOG_FAC(LOG_FTP)] = "ftp",
5249 [LOG_FAC(LOG_LOCAL0)] = "local0",
5250 [LOG_FAC(LOG_LOCAL1)] = "local1",
5251 [LOG_FAC(LOG_LOCAL2)] = "local2",
5252 [LOG_FAC(LOG_LOCAL3)] = "local3",
5253 [LOG_FAC(LOG_LOCAL4)] = "local4",
5254 [LOG_FAC(LOG_LOCAL5)] = "local5",
5255 [LOG_FAC(LOG_LOCAL6)] = "local6",
5256 [LOG_FAC(LOG_LOCAL7)] = "local7"
5259 DEFINE_STRING_TABLE_LOOKUP(log_facility_unshifted, int);
5261 static const char *const log_level_table[] = {
5262 [LOG_EMERG] = "emerg",
5263 [LOG_ALERT] = "alert",
5264 [LOG_CRIT] = "crit",
5266 [LOG_WARNING] = "warning",
5267 [LOG_NOTICE] = "notice",
5268 [LOG_INFO] = "info",
5269 [LOG_DEBUG] = "debug"
5272 DEFINE_STRING_TABLE_LOOKUP(log_level, int);
5274 static const char* const sched_policy_table[] = {
5275 [SCHED_OTHER] = "other",
5276 [SCHED_BATCH] = "batch",
5277 [SCHED_IDLE] = "idle",
5278 [SCHED_FIFO] = "fifo",
5282 DEFINE_STRING_TABLE_LOOKUP(sched_policy, int);
5284 static const char* const rlimit_table[] = {
5285 [RLIMIT_CPU] = "LimitCPU",
5286 [RLIMIT_FSIZE] = "LimitFSIZE",
5287 [RLIMIT_DATA] = "LimitDATA",
5288 [RLIMIT_STACK] = "LimitSTACK",
5289 [RLIMIT_CORE] = "LimitCORE",
5290 [RLIMIT_RSS] = "LimitRSS",
5291 [RLIMIT_NOFILE] = "LimitNOFILE",
5292 [RLIMIT_AS] = "LimitAS",
5293 [RLIMIT_NPROC] = "LimitNPROC",
5294 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
5295 [RLIMIT_LOCKS] = "LimitLOCKS",
5296 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
5297 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
5298 [RLIMIT_NICE] = "LimitNICE",
5299 [RLIMIT_RTPRIO] = "LimitRTPRIO",
5300 [RLIMIT_RTTIME] = "LimitRTTIME"
5303 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
5305 static const char* const ip_tos_table[] = {
5306 [IPTOS_LOWDELAY] = "low-delay",
5307 [IPTOS_THROUGHPUT] = "throughput",
5308 [IPTOS_RELIABILITY] = "reliability",
5309 [IPTOS_LOWCOST] = "low-cost",
5312 DEFINE_STRING_TABLE_LOOKUP(ip_tos, int);
5314 static const char *const __signal_table[] = {
5331 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
5342 [SIGVTALRM] = "VTALRM",
5344 [SIGWINCH] = "WINCH",
5350 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
5352 const char *signal_to_string(int signo) {
5353 static __thread char buf[12];
5356 name = __signal_to_string(signo);
5360 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
5361 snprintf(buf, sizeof(buf) - 1, "RTMIN+%d", signo - SIGRTMIN);
5363 snprintf(buf, sizeof(buf) - 1, "%d", signo);
5368 int signal_from_string(const char *s) {
5373 signo =__signal_from_string(s);
5377 if (startswith(s, "RTMIN+")) {
5381 if (safe_atou(s, &u) >= 0) {
5382 signo = (int) u + offset;
5383 if (signo > 0 && signo < _NSIG)
5389 bool kexec_loaded(void) {
5390 bool loaded = false;
5393 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
5401 int strdup_or_null(const char *a, char **b) {
5419 int prot_from_flags(int flags) {
5421 switch (flags & O_ACCMODE) {
5430 return PROT_READ|PROT_WRITE;
5437 char *format_bytes(char *buf, size_t l, off_t t) {
5440 static const struct {
5444 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5445 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5446 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
5447 { "G", 1024ULL*1024ULL*1024ULL },
5448 { "M", 1024ULL*1024ULL },
5452 for (i = 0; i < ELEMENTSOF(table); i++) {
5454 if (t >= table[i].factor) {
5457 (unsigned long long) (t / table[i].factor),
5458 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
5465 snprintf(buf, l, "%lluB", (unsigned long long) t);
5473 void* memdup(const void *p, size_t l) {
5486 int fd_inc_sndbuf(int fd, size_t n) {
5488 socklen_t l = sizeof(value);
5490 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
5492 l == sizeof(value) &&
5493 (size_t) value >= n*2)
5497 r = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value));
5504 int fd_inc_rcvbuf(int fd, size_t n) {
5506 socklen_t l = sizeof(value);
5508 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
5510 l == sizeof(value) &&
5511 (size_t) value >= n*2)
5515 r = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value));
5522 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
5523 pid_t parent_pid, agent_pid;
5525 bool stdout_is_tty, stderr_is_tty;
5533 parent_pid = getpid();
5535 /* Spawns a temporary TTY agent, making sure it goes away when
5542 if (agent_pid != 0) {
5549 * Make sure the agent goes away when the parent dies */
5550 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
5551 _exit(EXIT_FAILURE);
5553 /* Check whether our parent died before we were able
5554 * to set the death signal */
5555 if (getppid() != parent_pid)
5556 _exit(EXIT_SUCCESS);
5558 /* Don't leak fds to the agent */
5559 close_all_fds(except, n_except);
5561 stdout_is_tty = isatty(STDOUT_FILENO);
5562 stderr_is_tty = isatty(STDERR_FILENO);
5564 if (!stdout_is_tty || !stderr_is_tty) {
5565 /* Detach from stdout/stderr. and reopen
5566 * /dev/tty for them. This is important to
5567 * ensure that when systemctl is started via
5568 * popen() or a similar call that expects to
5569 * read EOF we actually do generate EOF and
5570 * not delay this indefinitely by because we
5571 * keep an unused copy of stdin around. */
5572 fd = open("/dev/tty", O_WRONLY);
5574 log_error("Failed to open /dev/tty: %m");
5575 _exit(EXIT_FAILURE);
5579 dup2(fd, STDOUT_FILENO);
5582 dup2(fd, STDERR_FILENO);
5588 /* Count arguments */
5590 for (n = 0; va_arg(ap, char*); n++)
5595 l = alloca(sizeof(char *) * (n + 1));
5597 /* Fill in arguments */
5599 for (i = 0; i <= n; i++)
5600 l[i] = va_arg(ap, char*);
5604 _exit(EXIT_FAILURE);
5607 int setrlimit_closest(int resource, const struct rlimit *rlim) {
5608 struct rlimit highest, fixed;
5612 if (setrlimit(resource, rlim) >= 0)
5618 /* So we failed to set the desired setrlimit, then let's try
5619 * to get as close as we can */
5620 assert_se(getrlimit(resource, &highest) == 0);
5622 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
5623 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
5625 if (setrlimit(resource, &fixed) < 0)
5631 int getenv_for_pid(pid_t pid, const char *field, char **_value) {
5632 char path[sizeof("/proc/")-1+10+sizeof("/environ")], *value = NULL;
5644 snprintf(path, sizeof(path), "/proc/%lu/environ", (unsigned long) pid);
5647 f = fopen(path, "re");
5655 char line[LINE_MAX];
5658 for (i = 0; i < sizeof(line)-1; i++) {
5662 if (_unlikely_(c == EOF)) {
5672 if (memcmp(line, field, l) == 0 && line[l] == '=') {
5673 value = strdup(line + l + 1);
5693 int can_sleep(const char *type) {
5694 char *p, *w, *state;
5701 r = read_one_line_file("/sys/power/state", &p);
5703 return r == -ENOENT ? 0 : r;
5707 FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state) {
5708 if (l == k && strncmp(w, type, l) == 0) {
5718 bool is_valid_documentation_url(const char *url) {
5721 if (startswith(url, "http://") && url[7])
5724 if (startswith(url, "https://") && url[8])
5727 if (startswith(url, "file:") && url[5])
5730 if (startswith(url, "info:") && url[5])
5733 if (startswith(url, "man:") && url[4])
5739 bool in_initrd(void) {
5740 static int saved = -1;
5743 saved = access("/etc/initrd-release", F_OK) >= 0;
5748 void warn_melody(void) {
5751 fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
5755 /* Yeah, this is synchronous. Kinda sucks. Bute well... */
5757 ioctl(fd, KIOCSOUND, (int)(1193180/440));
5758 usleep(125*USEC_PER_MSEC);
5760 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5761 usleep(125*USEC_PER_MSEC);
5763 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5764 usleep(125*USEC_PER_MSEC);
5766 ioctl(fd, KIOCSOUND, 0);
5767 close_nointr_nofail(fd);