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) {
3342 fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3345 if (errno != ENOTDIR)
3348 if (delete_root && !only_dirs)
3349 if (unlink(path) < 0 && errno != ENOENT)
3355 r = rm_rf_children(fd, only_dirs, honour_sticky, NULL);
3359 if (honour_sticky && file_is_priv_sticky(path) > 0)
3362 if (rmdir(path) < 0 && errno != ENOENT) {
3371 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
3374 /* Under the assumption that we are running privileged we
3375 * first change the access mode and only then hand out
3376 * ownership to avoid a window where access is too open. */
3378 if (mode != (mode_t) -1)
3379 if (chmod(path, mode) < 0)
3382 if (uid != (uid_t) -1 || gid != (gid_t) -1)
3383 if (chown(path, uid, gid) < 0)
3389 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
3392 /* Under the assumption that we are running privileged we
3393 * first change the access mode and only then hand out
3394 * ownership to avoid a window where access is too open. */
3396 if (fchmod(fd, mode) < 0)
3399 if (fchown(fd, uid, gid) < 0)
3405 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
3409 /* Allocates the cpuset in the right size */
3412 if (!(r = CPU_ALLOC(n)))
3415 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
3416 CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
3426 if (errno != EINVAL)
3433 void status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) {
3435 static const char status_indent[] = " "; /* "[" STATUS "] " */
3437 struct iovec iovec[5];
3442 /* This is independent of logging, as status messages are
3443 * optional and go exclusively to the console. */
3445 if (vasprintf(&s, format, ap) < 0)
3448 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
3461 sl = status ? strlen(status_indent) : 0;
3467 e = ellipsize(s, emax, 75);
3477 if (!isempty(status)) {
3478 IOVEC_SET_STRING(iovec[n++], "[");
3479 IOVEC_SET_STRING(iovec[n++], status);
3480 IOVEC_SET_STRING(iovec[n++], "] ");
3482 IOVEC_SET_STRING(iovec[n++], status_indent);
3485 IOVEC_SET_STRING(iovec[n++], s);
3486 IOVEC_SET_STRING(iovec[n++], "\n");
3488 writev(fd, iovec, n);
3494 close_nointr_nofail(fd);
3497 void status_printf(const char *status, bool ellipse, const char *format, ...) {
3502 va_start(ap, format);
3503 status_vprintf(status, ellipse, format, ap);
3507 void status_welcome(void) {
3508 char *pretty_name = NULL, *ansi_color = NULL;
3509 const char *const_pretty = NULL, *const_color = NULL;
3512 if ((r = parse_env_file("/etc/os-release", NEWLINE,
3513 "PRETTY_NAME", &pretty_name,
3514 "ANSI_COLOR", &ansi_color,
3518 log_warning("Failed to read /etc/os-release: %s", strerror(-r));
3521 if (!pretty_name && !const_pretty)
3522 const_pretty = "Linux";
3524 if (!ansi_color && !const_color)
3529 "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
3530 const_color ? const_color : ansi_color,
3531 const_pretty ? const_pretty : pretty_name);
3537 char *replace_env(const char *format, char **env) {
3544 const char *e, *word = format;
3549 for (e = format; *e; e ++) {
3560 if (!(k = strnappend(r, word, e-word-1)))
3569 } else if (*e == '$') {
3570 if (!(k = strnappend(r, word, e-word)))
3586 if (!(t = strv_env_get_with_length(env, word+2, e-word-2)))
3589 if (!(k = strappend(r, t)))
3602 if (!(k = strnappend(r, word, e-word)))
3613 char **replace_env_argv(char **argv, char **env) {
3615 unsigned k = 0, l = 0;
3617 l = strv_length(argv);
3619 if (!(r = new(char*, l+1)))
3622 STRV_FOREACH(i, argv) {
3624 /* If $FOO appears as single word, replace it by the split up variable */
3625 if ((*i)[0] == '$' && (*i)[1] != '{') {
3630 if ((e = strv_env_get(env, *i+1))) {
3632 if (!(m = strv_split_quoted(e))) {
3643 if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
3652 memcpy(r + k, m, q * sizeof(char*));
3660 /* If ${FOO} appears as part of a word, replace it by the variable as-is */
3661 if (!(r[k++] = replace_env(*i, env))) {
3671 int fd_columns(int fd) {
3675 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3684 unsigned columns(void) {
3685 static __thread int parsed_columns = 0;
3688 if (_likely_(parsed_columns > 0))
3689 return parsed_columns;
3691 e = getenv("COLUMNS");
3693 parsed_columns = atoi(e);
3695 if (parsed_columns <= 0)
3696 parsed_columns = fd_columns(STDOUT_FILENO);
3698 if (parsed_columns <= 0)
3699 parsed_columns = 80;
3701 return parsed_columns;
3704 int fd_lines(int fd) {
3708 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3717 unsigned lines(void) {
3718 static __thread int parsed_lines = 0;
3721 if (_likely_(parsed_lines > 0))
3722 return parsed_lines;
3724 e = getenv("LINES");
3726 parsed_lines = atoi(e);
3728 if (parsed_lines <= 0)
3729 parsed_lines = fd_lines(STDOUT_FILENO);
3731 if (parsed_lines <= 0)
3734 return parsed_lines;
3737 int running_in_chroot(void) {
3743 /* Only works as root */
3745 if (stat("/proc/1/root", &a) < 0)
3748 if (stat("/", &b) < 0)
3752 a.st_dev != b.st_dev ||
3753 a.st_ino != b.st_ino;
3756 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
3761 assert(percent <= 100);
3762 assert(new_length >= 3);
3764 if (old_length <= 3 || old_length <= new_length)
3765 return strndup(s, old_length);
3767 r = new0(char, new_length+1);
3771 x = (new_length * percent) / 100;
3773 if (x > new_length - 3)
3781 s + old_length - (new_length - x - 3),
3782 new_length - x - 3);
3787 char *ellipsize(const char *s, size_t length, unsigned percent) {
3788 return ellipsize_mem(s, strlen(s), length, percent);
3791 int touch(const char *path) {
3796 if ((fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644)) < 0)
3799 close_nointr_nofail(fd);
3803 char *unquote(const char *s, const char* quotes) {
3811 if (strchr(quotes, s[0]) && s[l-1] == s[0])
3812 return strndup(s+1, l-2);
3817 char *normalize_env_assignment(const char *s) {
3818 char *name, *value, *p, *r;
3823 if (!(r = strdup(s)))
3829 if (!(name = strndup(s, p - s)))
3832 if (!(p = strdup(p+1))) {
3837 value = unquote(strstrip(p), QUOTES);
3845 if (asprintf(&r, "%s=%s", name, value) < 0)
3854 int wait_for_terminate(pid_t pid, siginfo_t *status) {
3865 if (waitid(P_PID, pid, status, WEXITED) < 0) {
3877 int wait_for_terminate_and_warn(const char *name, pid_t pid) {
3884 if ((r = wait_for_terminate(pid, &status)) < 0) {
3885 log_warning("Failed to wait for %s: %s", name, strerror(-r));
3889 if (status.si_code == CLD_EXITED) {
3890 if (status.si_status != 0) {
3891 log_warning("%s failed with error code %i.", name, status.si_status);
3892 return status.si_status;
3895 log_debug("%s succeeded.", name);
3898 } else if (status.si_code == CLD_KILLED ||
3899 status.si_code == CLD_DUMPED) {
3901 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
3905 log_warning("%s failed due to unknown reason.", name);
3910 _noreturn_ void freeze(void) {
3912 /* Make sure nobody waits for us on a socket anymore */
3913 close_all_fds(NULL, 0);
3921 bool null_or_empty(struct stat *st) {
3924 if (S_ISREG(st->st_mode) && st->st_size <= 0)
3927 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
3933 int null_or_empty_path(const char *fn) {
3938 if (stat(fn, &st) < 0)
3941 return null_or_empty(&st);
3944 DIR *xopendirat(int fd, const char *name, int flags) {
3948 if ((nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags)) < 0)
3951 if (!(d = fdopendir(nfd))) {
3952 close_nointr_nofail(nfd);
3959 int signal_from_string_try_harder(const char *s) {
3963 if ((signo = signal_from_string(s)) <= 0)
3964 if (startswith(s, "SIG"))
3965 return signal_from_string(s+3);
3970 void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) {
3976 if (!dual_timestamp_is_set(t))
3979 fprintf(f, "%s=%llu %llu\n",
3981 (unsigned long long) t->realtime,
3982 (unsigned long long) t->monotonic);
3985 void dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
3986 unsigned long long a, b;
3991 if (sscanf(value, "%lli %llu", &a, &b) != 2)
3992 log_debug("Failed to parse finish timestamp value %s", value);
3999 char *fstab_node_to_udev_node(const char *p) {
4003 /* FIXME: to follow udev's logic 100% we need to leave valid
4004 * UTF8 chars unescaped */
4006 if (startswith(p, "LABEL=")) {
4008 if (!(u = unquote(p+6, "\"\'")))
4011 t = xescape(u, "/ ");
4017 r = asprintf(&dn, "/dev/disk/by-label/%s", t);
4026 if (startswith(p, "UUID=")) {
4028 if (!(u = unquote(p+5, "\"\'")))
4031 t = xescape(u, "/ ");
4037 r = asprintf(&dn, "/dev/disk/by-uuid/%s", t);
4049 bool tty_is_vc(const char *tty) {
4052 if (startswith(tty, "/dev/"))
4055 return vtnr_from_tty(tty) >= 0;
4058 bool tty_is_console(const char *tty) {
4061 if (startswith(tty, "/dev/"))
4064 return streq(tty, "console");
4067 int vtnr_from_tty(const char *tty) {
4072 if (startswith(tty, "/dev/"))
4075 if (!startswith(tty, "tty") )
4078 if (tty[3] < '0' || tty[3] > '9')
4081 r = safe_atoi(tty+3, &i);
4085 if (i < 0 || i > 63)
4091 bool tty_is_vc_resolve(const char *tty) {
4092 char *active = NULL;
4097 if (startswith(tty, "/dev/"))
4100 /* Resolve where /dev/console is pointing to, if /sys is
4101 * actually ours (i.e. not read-only-mounted which is a sign
4102 * for container setups) */
4103 if (streq(tty, "console") && path_is_read_only_fs("/sys") <= 0)
4104 if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) {
4105 /* If multiple log outputs are configured the
4106 * last one is what /dev/console points to */
4107 tty = strrchr(active, ' ');
4120 const char *default_term_for_tty(const char *tty) {
4123 return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102";
4126 bool dirent_is_file(const struct dirent *de) {
4129 if (ignore_file(de->d_name))
4132 if (de->d_type != DT_REG &&
4133 de->d_type != DT_LNK &&
4134 de->d_type != DT_UNKNOWN)
4140 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
4143 if (!dirent_is_file(de))
4146 return endswith(de->d_name, suffix);
4149 void execute_directory(const char *directory, DIR *d, char *argv[]) {
4152 Hashmap *pids = NULL;
4156 /* Executes all binaries in a directory in parallel and waits
4157 * until all they all finished. */
4160 if (!(_d = opendir(directory))) {
4162 if (errno == ENOENT)
4165 log_error("Failed to enumerate directory %s: %m", directory);
4172 if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) {
4173 log_error("Failed to allocate set.");
4177 while ((de = readdir(d))) {
4182 if (!dirent_is_file(de))
4185 if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
4186 log_error("Out of memory");
4190 if ((pid = fork()) < 0) {
4191 log_error("Failed to fork: %m");
4209 log_error("Failed to execute %s: %m", path);
4210 _exit(EXIT_FAILURE);
4213 log_debug("Spawned %s as %lu", path, (unsigned long) pid);
4215 if ((k = hashmap_put(pids, UINT_TO_PTR(pid), path)) < 0) {
4216 log_error("Failed to add PID to set: %s", strerror(-k));
4221 while (!hashmap_isempty(pids)) {
4222 pid_t pid = PTR_TO_UINT(hashmap_first_key(pids));
4227 if (waitid(P_PID, pid, &si, WEXITED) < 0) {
4232 log_error("waitid() failed: %m");
4236 if ((path = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) {
4237 if (!is_clean_exit(si.si_code, si.si_status)) {
4238 if (si.si_code == CLD_EXITED)
4239 log_error("%s exited with exit status %i.", path, si.si_status);
4241 log_error("%s terminated by signal %s.", path, signal_to_string(si.si_status));
4243 log_debug("%s exited successfully.", path);
4254 hashmap_free_free(pids);
4257 int kill_and_sigcont(pid_t pid, int sig) {
4260 r = kill(pid, sig) < 0 ? -errno : 0;
4268 bool nulstr_contains(const char*nulstr, const char *needle) {
4274 NULSTR_FOREACH(i, nulstr)
4275 if (streq(i, needle))
4281 bool plymouth_running(void) {
4282 return access("/run/plymouth/pid", F_OK) >= 0;
4285 void parse_syslog_priority(char **p, int *priority) {
4286 int a = 0, b = 0, c = 0;
4296 if (!strchr(*p, '>'))
4299 if ((*p)[2] == '>') {
4300 c = undecchar((*p)[1]);
4302 } else if ((*p)[3] == '>') {
4303 b = undecchar((*p)[1]);
4304 c = undecchar((*p)[2]);
4306 } else if ((*p)[4] == '>') {
4307 a = undecchar((*p)[1]);
4308 b = undecchar((*p)[2]);
4309 c = undecchar((*p)[3]);
4314 if (a < 0 || b < 0 || c < 0)
4317 *priority = a*100+b*10+c;
4321 void skip_syslog_pid(char **buf) {
4333 p += strspn(p, "0123456789");
4343 void skip_syslog_date(char **buf) {
4351 LETTER, LETTER, LETTER,
4353 SPACE_OR_NUMBER, NUMBER,
4355 SPACE_OR_NUMBER, NUMBER,
4357 SPACE_OR_NUMBER, NUMBER,
4359 SPACE_OR_NUMBER, NUMBER,
4371 for (i = 0; i < ELEMENTSOF(sequence); i++, p++) {
4376 switch (sequence[i]) {
4383 case SPACE_OR_NUMBER:
4390 if (*p < '0' || *p > '9')
4396 if (!(*p >= 'A' && *p <= 'Z') &&
4397 !(*p >= 'a' && *p <= 'z'))
4413 char* strshorten(char *s, size_t l) {
4422 static bool hostname_valid_char(char c) {
4424 (c >= 'a' && c <= 'z') ||
4425 (c >= 'A' && c <= 'Z') ||
4426 (c >= '0' && c <= '9') ||
4432 bool hostname_is_valid(const char *s) {
4438 for (p = s; *p; p++)
4439 if (!hostname_valid_char(*p))
4442 if (p-s > HOST_NAME_MAX)
4448 char* hostname_cleanup(char *s) {
4451 for (p = s, d = s; *p; p++)
4452 if ((*p >= 'a' && *p <= 'z') ||
4453 (*p >= 'A' && *p <= 'Z') ||
4454 (*p >= '0' && *p <= '9') ||
4462 strshorten(s, HOST_NAME_MAX);
4466 int pipe_eof(int fd) {
4467 struct pollfd pollfd;
4472 pollfd.events = POLLIN|POLLHUP;
4474 r = poll(&pollfd, 1, 0);
4481 return pollfd.revents & POLLHUP;
4484 int fd_wait_for_event(int fd, int event, usec_t t) {
4485 struct pollfd pollfd;
4490 pollfd.events = event;
4492 r = poll(&pollfd, 1, t == (usec_t) -1 ? -1 : (int) (t / USEC_PER_MSEC));
4499 return pollfd.revents;
4502 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
4513 t = new(char, strlen(path) + 1 + 6 + 1);
4517 fn = path_get_file_name(path);
4521 stpcpy(stpcpy(t+k+1, fn), "XXXXXX");
4523 fd = mkostemp(t, O_WRONLY|O_CLOEXEC);
4529 f = fdopen(fd, "we");
4542 int terminal_vhangup_fd(int fd) {
4545 if (ioctl(fd, TIOCVHANGUP) < 0)
4551 int terminal_vhangup(const char *name) {
4554 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4558 r = terminal_vhangup_fd(fd);
4559 close_nointr_nofail(fd);
4564 int vt_disallocate(const char *name) {
4568 /* Deallocate the VT if possible. If not possible
4569 * (i.e. because it is the active one), at least clear it
4570 * entirely (including the scrollback buffer) */
4572 if (!startswith(name, "/dev/"))
4575 if (!tty_is_vc(name)) {
4576 /* So this is not a VT. I guess we cannot deallocate
4577 * it then. But let's at least clear the screen */
4579 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4584 "\033[r" /* clear scrolling region */
4585 "\033[H" /* move home */
4586 "\033[2J", /* clear screen */
4588 close_nointr_nofail(fd);
4593 if (!startswith(name, "/dev/tty"))
4596 r = safe_atou(name+8, &u);
4603 /* Try to deallocate */
4604 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
4608 r = ioctl(fd, VT_DISALLOCATE, u);
4609 close_nointr_nofail(fd);
4617 /* Couldn't deallocate, so let's clear it fully with
4619 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4624 "\033[r" /* clear scrolling region */
4625 "\033[H" /* move home */
4626 "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
4628 close_nointr_nofail(fd);
4633 int copy_file(const char *from, const char *to) {
4639 fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
4643 fdt = open(to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY, 0644);
4645 close_nointr_nofail(fdf);
4653 n = read(fdf, buf, sizeof(buf));
4657 close_nointr_nofail(fdf);
4668 k = loop_write(fdt, buf, n, false);
4670 r = k < 0 ? k : (errno ? -errno : -EIO);
4672 close_nointr_nofail(fdf);
4680 close_nointr_nofail(fdf);
4681 r = close_nointr(fdt);
4691 int symlink_or_copy(const char *from, const char *to) {
4692 char *pf = NULL, *pt = NULL;
4699 if (path_get_parent(from, &pf) < 0 ||
4700 path_get_parent(to, &pt) < 0) {
4705 if (stat(pf, &a) < 0 ||
4711 if (a.st_dev != b.st_dev) {
4715 return copy_file(from, to);
4718 if (symlink(from, to) < 0) {
4732 int symlink_or_copy_atomic(const char *from, const char *to) {
4736 unsigned long long ull;
4743 t = new(char, strlen(to) + 1 + 16 + 1);
4747 fn = path_get_file_name(to);
4751 x = stpcpy(t+k+1, fn);
4754 for (i = 0; i < 16; i++) {
4755 *(x++) = hexchar(ull & 0xF);
4761 r = symlink_or_copy(from, t);
4768 if (rename(t, to) < 0) {
4779 bool display_is_local(const char *display) {
4783 display[0] == ':' &&
4784 display[1] >= '0' &&
4788 int socket_from_display(const char *display, char **path) {
4795 if (!display_is_local(display))
4798 k = strspn(display+1, "0123456789");
4800 f = new(char, sizeof("/tmp/.X11-unix/X") + k);
4804 c = stpcpy(f, "/tmp/.X11-unix/X");
4805 memcpy(c, display+1, k);
4813 int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home) {
4820 /* We enforce some special rules for uid=0: in order to avoid
4821 * NSS lookups for root we hardcode its data. */
4823 if (streq(*username, "root") || streq(*username, "0")) {
4837 if (parse_uid(*username, &u) >= 0) {
4841 /* If there are multiple users with the same id, make
4842 * sure to leave $USER to the configured value instead
4843 * of the first occurrence in the database. However if
4844 * the uid was configured by a numeric uid, then let's
4845 * pick the real username from /etc/passwd. */
4847 *username = p->pw_name;
4850 p = getpwnam(*username);
4854 return errno != 0 ? -errno : -ESRCH;
4868 int get_group_creds(const char **groupname, gid_t *gid) {
4874 /* We enforce some special rules for gid=0: in order to avoid
4875 * NSS lookups for root we hardcode its data. */
4877 if (streq(*groupname, "root") || streq(*groupname, "0")) {
4878 *groupname = "root";
4886 if (parse_gid(*groupname, &id) >= 0) {
4891 *groupname = g->gr_name;
4894 g = getgrnam(*groupname);
4898 return errno != 0 ? -errno : -ESRCH;
4906 int in_group(const char *name) {
4908 int ngroups_max, r, i;
4910 r = get_group_creds(&name, &gid);
4914 if (getgid() == gid)
4917 if (getegid() == gid)
4920 ngroups_max = sysconf(_SC_NGROUPS_MAX);
4921 assert(ngroups_max > 0);
4923 gids = alloca(sizeof(gid_t) * ngroups_max);
4925 r = getgroups(ngroups_max, gids);
4929 for (i = 0; i < r; i++)
4936 int glob_exists(const char *path) {
4944 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
4946 if (k == GLOB_NOMATCH)
4948 else if (k == GLOB_NOSPACE)
4951 r = !strv_isempty(g.gl_pathv);
4953 r = errno ? -errno : -EIO;
4960 int dirent_ensure_type(DIR *d, struct dirent *de) {
4966 if (de->d_type != DT_UNKNOWN)
4969 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
4973 S_ISREG(st.st_mode) ? DT_REG :
4974 S_ISDIR(st.st_mode) ? DT_DIR :
4975 S_ISLNK(st.st_mode) ? DT_LNK :
4976 S_ISFIFO(st.st_mode) ? DT_FIFO :
4977 S_ISSOCK(st.st_mode) ? DT_SOCK :
4978 S_ISCHR(st.st_mode) ? DT_CHR :
4979 S_ISBLK(st.st_mode) ? DT_BLK :
4985 int in_search_path(const char *path, char **search) {
4989 r = path_get_parent(path, &parent);
4995 STRV_FOREACH(i, search) {
4996 if (path_equal(parent, *i)) {
5007 int get_files_in_directory(const char *path, char ***list) {
5015 /* Returns all files in a directory in *list, and the number
5016 * of files as return value. If list is NULL returns only the
5024 struct dirent buffer, *de;
5027 k = readdir_r(d, &buffer, &de);
5036 dirent_ensure_type(d, de);
5038 if (!dirent_is_file(de))
5042 if ((unsigned) r >= n) {
5046 t = realloc(l, sizeof(char*) * n);
5055 assert((unsigned) r < n);
5057 l[r] = strdup(de->d_name);
5081 char *join(const char *x, ...) {
5094 t = va_arg(ap, const char *);
5117 t = va_arg(ap, const char *);
5131 bool is_main_thread(void) {
5132 static __thread int cached = 0;
5134 if (_unlikely_(cached == 0))
5135 cached = getpid() == gettid() ? 1 : -1;
5140 int block_get_whole_disk(dev_t d, dev_t *ret) {
5147 /* If it has a queue this is good enough for us */
5148 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
5151 r = access(p, F_OK);
5159 /* If it is a partition find the originating device */
5160 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
5163 r = access(p, F_OK);
5169 /* Get parent dev_t */
5170 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
5173 r = read_one_line_file(p, &s);
5179 r = sscanf(s, "%u:%u", &m, &n);
5185 /* Only return this if it is really good enough for us. */
5186 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
5189 r = access(p, F_OK);
5193 *ret = makedev(m, n);
5200 int file_is_priv_sticky(const char *p) {
5205 if (lstat(p, &st) < 0)
5209 (st.st_uid == 0 || st.st_uid == getuid()) &&
5210 (st.st_mode & S_ISVTX);
5213 static const char *const ioprio_class_table[] = {
5214 [IOPRIO_CLASS_NONE] = "none",
5215 [IOPRIO_CLASS_RT] = "realtime",
5216 [IOPRIO_CLASS_BE] = "best-effort",
5217 [IOPRIO_CLASS_IDLE] = "idle"
5220 DEFINE_STRING_TABLE_LOOKUP(ioprio_class, int);
5222 static const char *const sigchld_code_table[] = {
5223 [CLD_EXITED] = "exited",
5224 [CLD_KILLED] = "killed",
5225 [CLD_DUMPED] = "dumped",
5226 [CLD_TRAPPED] = "trapped",
5227 [CLD_STOPPED] = "stopped",
5228 [CLD_CONTINUED] = "continued",
5231 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
5233 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
5234 [LOG_FAC(LOG_KERN)] = "kern",
5235 [LOG_FAC(LOG_USER)] = "user",
5236 [LOG_FAC(LOG_MAIL)] = "mail",
5237 [LOG_FAC(LOG_DAEMON)] = "daemon",
5238 [LOG_FAC(LOG_AUTH)] = "auth",
5239 [LOG_FAC(LOG_SYSLOG)] = "syslog",
5240 [LOG_FAC(LOG_LPR)] = "lpr",
5241 [LOG_FAC(LOG_NEWS)] = "news",
5242 [LOG_FAC(LOG_UUCP)] = "uucp",
5243 [LOG_FAC(LOG_CRON)] = "cron",
5244 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
5245 [LOG_FAC(LOG_FTP)] = "ftp",
5246 [LOG_FAC(LOG_LOCAL0)] = "local0",
5247 [LOG_FAC(LOG_LOCAL1)] = "local1",
5248 [LOG_FAC(LOG_LOCAL2)] = "local2",
5249 [LOG_FAC(LOG_LOCAL3)] = "local3",
5250 [LOG_FAC(LOG_LOCAL4)] = "local4",
5251 [LOG_FAC(LOG_LOCAL5)] = "local5",
5252 [LOG_FAC(LOG_LOCAL6)] = "local6",
5253 [LOG_FAC(LOG_LOCAL7)] = "local7"
5256 DEFINE_STRING_TABLE_LOOKUP(log_facility_unshifted, int);
5258 static const char *const log_level_table[] = {
5259 [LOG_EMERG] = "emerg",
5260 [LOG_ALERT] = "alert",
5261 [LOG_CRIT] = "crit",
5263 [LOG_WARNING] = "warning",
5264 [LOG_NOTICE] = "notice",
5265 [LOG_INFO] = "info",
5266 [LOG_DEBUG] = "debug"
5269 DEFINE_STRING_TABLE_LOOKUP(log_level, int);
5271 static const char* const sched_policy_table[] = {
5272 [SCHED_OTHER] = "other",
5273 [SCHED_BATCH] = "batch",
5274 [SCHED_IDLE] = "idle",
5275 [SCHED_FIFO] = "fifo",
5279 DEFINE_STRING_TABLE_LOOKUP(sched_policy, int);
5281 static const char* const rlimit_table[] = {
5282 [RLIMIT_CPU] = "LimitCPU",
5283 [RLIMIT_FSIZE] = "LimitFSIZE",
5284 [RLIMIT_DATA] = "LimitDATA",
5285 [RLIMIT_STACK] = "LimitSTACK",
5286 [RLIMIT_CORE] = "LimitCORE",
5287 [RLIMIT_RSS] = "LimitRSS",
5288 [RLIMIT_NOFILE] = "LimitNOFILE",
5289 [RLIMIT_AS] = "LimitAS",
5290 [RLIMIT_NPROC] = "LimitNPROC",
5291 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
5292 [RLIMIT_LOCKS] = "LimitLOCKS",
5293 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
5294 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
5295 [RLIMIT_NICE] = "LimitNICE",
5296 [RLIMIT_RTPRIO] = "LimitRTPRIO",
5297 [RLIMIT_RTTIME] = "LimitRTTIME"
5300 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
5302 static const char* const ip_tos_table[] = {
5303 [IPTOS_LOWDELAY] = "low-delay",
5304 [IPTOS_THROUGHPUT] = "throughput",
5305 [IPTOS_RELIABILITY] = "reliability",
5306 [IPTOS_LOWCOST] = "low-cost",
5309 DEFINE_STRING_TABLE_LOOKUP(ip_tos, int);
5311 static const char *const __signal_table[] = {
5328 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
5339 [SIGVTALRM] = "VTALRM",
5341 [SIGWINCH] = "WINCH",
5347 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
5349 const char *signal_to_string(int signo) {
5350 static __thread char buf[12];
5353 name = __signal_to_string(signo);
5357 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
5358 snprintf(buf, sizeof(buf) - 1, "RTMIN+%d", signo - SIGRTMIN);
5360 snprintf(buf, sizeof(buf) - 1, "%d", signo);
5365 int signal_from_string(const char *s) {
5370 signo =__signal_from_string(s);
5374 if (startswith(s, "RTMIN+")) {
5378 if (safe_atou(s, &u) >= 0) {
5379 signo = (int) u + offset;
5380 if (signo > 0 && signo < _NSIG)
5386 bool kexec_loaded(void) {
5387 bool loaded = false;
5390 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
5398 int strdup_or_null(const char *a, char **b) {
5416 int prot_from_flags(int flags) {
5418 switch (flags & O_ACCMODE) {
5427 return PROT_READ|PROT_WRITE;
5434 char *format_bytes(char *buf, size_t l, off_t t) {
5437 static const struct {
5441 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5442 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5443 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
5444 { "G", 1024ULL*1024ULL*1024ULL },
5445 { "M", 1024ULL*1024ULL },
5449 for (i = 0; i < ELEMENTSOF(table); i++) {
5451 if (t >= table[i].factor) {
5454 (unsigned long long) (t / table[i].factor),
5455 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
5462 snprintf(buf, l, "%lluB", (unsigned long long) t);
5470 void* memdup(const void *p, size_t l) {
5483 int fd_inc_sndbuf(int fd, size_t n) {
5485 socklen_t l = sizeof(value);
5487 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
5489 l == sizeof(value) &&
5490 (size_t) value >= n*2)
5494 r = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value));
5501 int fd_inc_rcvbuf(int fd, size_t n) {
5503 socklen_t l = sizeof(value);
5505 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
5507 l == sizeof(value) &&
5508 (size_t) value >= n*2)
5512 r = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value));
5519 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
5520 pid_t parent_pid, agent_pid;
5522 bool stdout_is_tty, stderr_is_tty;
5530 parent_pid = getpid();
5532 /* Spawns a temporary TTY agent, making sure it goes away when
5539 if (agent_pid != 0) {
5546 * Make sure the agent goes away when the parent dies */
5547 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
5548 _exit(EXIT_FAILURE);
5550 /* Check whether our parent died before we were able
5551 * to set the death signal */
5552 if (getppid() != parent_pid)
5553 _exit(EXIT_SUCCESS);
5555 /* Don't leak fds to the agent */
5556 close_all_fds(except, n_except);
5558 stdout_is_tty = isatty(STDOUT_FILENO);
5559 stderr_is_tty = isatty(STDERR_FILENO);
5561 if (!stdout_is_tty || !stderr_is_tty) {
5562 /* Detach from stdout/stderr. and reopen
5563 * /dev/tty for them. This is important to
5564 * ensure that when systemctl is started via
5565 * popen() or a similar call that expects to
5566 * read EOF we actually do generate EOF and
5567 * not delay this indefinitely by because we
5568 * keep an unused copy of stdin around. */
5569 fd = open("/dev/tty", O_WRONLY);
5571 log_error("Failed to open /dev/tty: %m");
5572 _exit(EXIT_FAILURE);
5576 dup2(fd, STDOUT_FILENO);
5579 dup2(fd, STDERR_FILENO);
5585 /* Count arguments */
5587 for (n = 0; va_arg(ap, char*); n++)
5592 l = alloca(sizeof(char *) * (n + 1));
5594 /* Fill in arguments */
5596 for (i = 0; i <= n; i++)
5597 l[i] = va_arg(ap, char*);
5601 _exit(EXIT_FAILURE);
5604 int setrlimit_closest(int resource, const struct rlimit *rlim) {
5605 struct rlimit highest, fixed;
5609 if (setrlimit(resource, rlim) >= 0)
5615 /* So we failed to set the desired setrlimit, then let's try
5616 * to get as close as we can */
5617 assert_se(getrlimit(resource, &highest) == 0);
5619 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
5620 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
5622 if (setrlimit(resource, &fixed) < 0)
5628 int getenv_for_pid(pid_t pid, const char *field, char **_value) {
5629 char path[sizeof("/proc/")-1+10+sizeof("/environ")], *value = NULL;
5641 snprintf(path, sizeof(path), "/proc/%lu/environ", (unsigned long) pid);
5644 f = fopen(path, "re");
5652 char line[LINE_MAX];
5655 for (i = 0; i < sizeof(line)-1; i++) {
5659 if (_unlikely_(c == EOF)) {
5669 if (memcmp(line, field, l) == 0 && line[l] == '=') {
5670 value = strdup(line + l + 1);
5690 int can_sleep(const char *type) {
5691 char *p, *w, *state;
5698 r = read_one_line_file("/sys/power/state", &p);
5700 return r == -ENOENT ? 0 : r;
5704 FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state) {
5705 if (l == k && strncmp(w, type, l) == 0) {
5715 bool is_valid_documentation_url(const char *url) {
5718 if (startswith(url, "http://") && url[7])
5721 if (startswith(url, "https://") && url[8])
5724 if (startswith(url, "file:") && url[5])
5727 if (startswith(url, "info:") && url[5])
5730 if (startswith(url, "man:") && url[4])
5736 bool in_initrd(void) {
5737 static int saved = -1;
5740 saved = access("/etc/initrd-release", F_OK) >= 0;
5745 void warn_melody(void) {
5748 fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
5752 /* Yeah, this is synchronous. Kinda sucks. Bute well... */
5754 ioctl(fd, KIOCSOUND, (int)(1193180/440));
5755 usleep(125*USEC_PER_MSEC);
5757 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5758 usleep(125*USEC_PER_MSEC);
5760 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5761 usleep(125*USEC_PER_MSEC);
5763 ioctl(fd, KIOCSOUND, 0);
5764 close_nointr_nofail(fd);