1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
31 #include <sys/resource.h>
32 #include <linux/sched.h>
33 #include <sys/types.h>
37 #include <sys/ioctl.h>
39 #include <linux/tiocl.h>
42 #include <sys/inotify.h>
46 #include <sys/prctl.h>
47 #include <sys/utsname.h>
49 #include <netinet/ip.h>
58 #include <linux/magic.h>
70 #include "path-util.h"
71 #include "exit-status.h"
75 char **saved_argv = NULL;
77 static volatile unsigned cached_columns = 0;
78 static volatile unsigned cached_lines = 0;
80 bool is_efiboot(void) {
81 return access("/sys/firmware/efi", F_OK) >= 0;
84 size_t page_size(void) {
85 static __thread size_t pgsz = 0;
88 if (_likely_(pgsz > 0))
91 r = sysconf(_SC_PAGESIZE);
98 bool streq_ptr(const char *a, const char *b) {
100 /* Like streq(), but tries to make sense of NULL pointers */
111 char* endswith(const char *s, const char *postfix) {
118 pl = strlen(postfix);
121 return (char*) s + sl;
126 if (memcmp(s + sl - pl, postfix, pl) != 0)
129 return (char*) s + sl - pl;
132 char* startswith(const char *s, const char *prefix) {
149 char* startswith_no_case(const char *s, const char *prefix) {
159 if (tolower(*a) != tolower(*b))
166 bool first_word(const char *s, const char *word) {
181 if (memcmp(s, word, wl) != 0)
185 strchr(WHITESPACE, s[wl]);
188 int close_nointr(int fd) {
203 void close_nointr_nofail(int fd) {
204 int saved_errno = errno;
206 /* like close_nointr() but cannot fail, and guarantees errno
209 assert_se(close_nointr(fd) == 0);
214 void close_many(const int fds[], unsigned n_fd) {
217 for (i = 0; i < n_fd; i++)
218 close_nointr_nofail(fds[i]);
221 int parse_boolean(const char *v) {
224 if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
226 else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
232 int parse_pid(const char *s, pid_t* ret_pid) {
233 unsigned long ul = 0;
240 r = safe_atolu(s, &ul);
246 if ((unsigned long) pid != ul)
256 int parse_uid(const char *s, uid_t* ret_uid) {
257 unsigned long ul = 0;
264 r = safe_atolu(s, &ul);
270 if ((unsigned long) uid != ul)
277 int safe_atou(const char *s, unsigned *ret_u) {
285 l = strtoul(s, &x, 0);
287 if (!x || x == s || *x || errno)
288 return errno ? -errno : -EINVAL;
290 if ((unsigned long) (unsigned) l != l)
293 *ret_u = (unsigned) l;
297 int safe_atoi(const char *s, int *ret_i) {
305 l = strtol(s, &x, 0);
307 if (!x || x == s || *x || errno)
308 return errno ? -errno : -EINVAL;
310 if ((long) (int) l != l)
317 int safe_atollu(const char *s, long long unsigned *ret_llu) {
319 unsigned long long l;
325 l = strtoull(s, &x, 0);
327 if (!x || x == s || *x || errno)
328 return errno ? -errno : -EINVAL;
334 int safe_atolli(const char *s, long long int *ret_lli) {
342 l = strtoll(s, &x, 0);
344 if (!x || x == s || *x || errno)
345 return errno ? -errno : -EINVAL;
351 /* Split a string into words. */
352 char *split(const char *c, size_t *l, const char *separator, char **state) {
355 current = *state ? *state : (char*) c;
357 if (!*current || *c == 0)
360 current += strspn(current, separator);
361 *l = strcspn(current, separator);
364 return (char*) current;
367 /* Split a string into words, but consider strings enclosed in '' and
368 * "" as words even if they include spaces. */
369 char *split_quoted(const char *c, size_t *l, char **state) {
371 bool escaped = false;
373 current = *state ? *state : (char*) c;
375 if (!*current || *c == 0)
378 current += strspn(current, WHITESPACE);
380 if (*current == '\'') {
383 for (e = current; *e; e++) {
393 *state = *e == 0 ? e : e+1;
394 } else if (*current == '\"') {
397 for (e = current; *e; e++) {
407 *state = *e == 0 ? e : e+1;
409 for (e = current; *e; e++) {
414 else if (strchr(WHITESPACE, *e))
421 return (char*) current;
424 int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
426 _cleanup_fclose_ FILE *f = NULL;
427 char fn[PATH_MAX], line[LINE_MAX], *p;
433 assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1));
440 if (!fgets(line, sizeof(line), f)) {
441 r = feof(f) ? -EIO : -errno;
445 /* Let's skip the pid and comm fields. The latter is enclosed
446 * in () but does not escape any () in its value, so let's
447 * skip over it manually */
449 p = strrchr(line, ')');
461 if ((long unsigned) (pid_t) ppid != ppid)
464 *_ppid = (pid_t) ppid;
469 int get_starttime_of_pid(pid_t pid, unsigned long long *st) {
470 _cleanup_fclose_ FILE *f = NULL;
471 char fn[PATH_MAX], line[LINE_MAX], *p;
476 assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1));
483 if (!fgets(line, sizeof(line), f)) {
490 /* Let's skip the pid and comm fields. The latter is enclosed
491 * in () but does not escape any () in its value, so let's
492 * skip over it manually */
494 p = strrchr(line, ')');
516 "%*d " /* priority */
518 "%*d " /* num_threads */
519 "%*d " /* itrealvalue */
520 "%llu " /* starttime */,
527 int write_one_line_file(const char *fn, const char *line) {
528 _cleanup_fclose_ FILE *f = NULL;
538 if (fputs(line, f) < 0)
539 return errno ? -errno : -EIO;
541 if (!endswith(line, "\n"))
547 return errno ? -errno : -EIO;
552 int fchmod_umask(int fd, mode_t m) {
557 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
563 int write_one_line_file_atomic(const char *fn, const char *line) {
571 r = fopen_temporary(fn, &f, &p);
575 fchmod_umask(fileno(f), 0644);
578 if (fputs(line, f) < 0) {
583 if (!endswith(line, "\n"))
594 if (rename(p, fn) < 0)
610 int read_one_line_file(const char *fn, char **line) {
611 _cleanup_fclose_ FILE *f = NULL;
612 char t[LINE_MAX], *c;
621 if (!fgets(t, sizeof(t), f)) {
624 return errno ? -errno : -EIO;
638 int read_full_file(const char *fn, char **contents, size_t *size) {
639 _cleanup_fclose_ FILE *f = NULL;
641 _cleanup_free_ char *buf = NULL;
648 if (fstat(fileno(f), &st) < 0)
652 if (st.st_size > 4*1024*1024)
655 n = st.st_size > 0 ? st.st_size : LINE_MAX;
662 t = realloc(buf, n+1);
667 k = fread(buf + l, 1, n - l, f);
696 const char *separator, ...) {
699 char *contents = NULL, *p;
704 if ((r = read_full_file(fname, &contents, NULL)) < 0)
709 const char *key = NULL;
711 p += strspn(p, separator);
712 p += strspn(p, WHITESPACE);
717 if (!strchr(COMMENTS, *p)) {
721 va_start(ap, separator);
722 while ((key = va_arg(ap, char *))) {
726 value = va_arg(ap, char **);
729 if (strncmp(p, key, n) != 0 ||
734 n = strcspn(p, separator);
737 strchr(QUOTES, p[0]) &&
739 v = strndup(p+1, n-2);
750 /* return empty value strings as NULL */
767 p += strcspn(p, separator);
786 if (!(f = fopen(fname, "re")))
790 char l[LINE_MAX], *p, *u;
793 if (!fgets(l, sizeof(l), f)) {
806 if (strchr(COMMENTS, *p))
809 if (!(u = normalize_env_assignment(p))) {
814 t = strv_append(m, u);
840 int write_env_file(const char *fname, char **l) {
845 r = fopen_temporary(fname, &f, &p);
849 fchmod_umask(fileno(f), 0644);
865 if (rename(p, fname) < 0)
880 char *truncate_nl(char *s) {
883 s[strcspn(s, NEWLINE)] = 0;
887 int get_process_comm(pid_t pid, char **name) {
893 r = read_one_line_file("/proc/self/comm", name);
896 if (asprintf(&p, "/proc/%lu/comm", (unsigned long) pid) < 0)
899 r = read_one_line_file(p, name);
906 int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
914 f = fopen("/proc/self/cmdline", "re");
917 if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
926 if (max_length == 0) {
928 while ((c = getc(f)) != EOF) {
929 k = realloc(r, len+1);
936 r[len-1] = isprint(c) ? c : ' ';
943 r = new(char, max_length);
951 while ((c = getc(f)) != EOF) {
973 size_t n = MIN(left-1, 3U);
982 /* Kernel threads have no argv[] */
983 if (r == NULL || r[0] == 0) {
992 h = get_process_comm(pid, &t);
996 r = strjoin("[", t, "]", NULL);
1007 int is_kernel_thread(pid_t pid) {
1017 if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
1026 count = fread(&c, 1, 1, f);
1030 /* Kernel threads have an empty cmdline */
1033 return eof ? 1 : -errno;
1038 int get_process_exe(pid_t pid, char **name) {
1044 r = readlink_malloc("/proc/self/exe", name);
1047 if (asprintf(&p, "/proc/%lu/exe", (unsigned long) pid) < 0)
1050 r = readlink_malloc(p, name);
1057 static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
1067 if (asprintf(&p, "/proc/%lu/status", (unsigned long) pid) < 0)
1077 char line[LINE_MAX], *l;
1079 if (!fgets(line, sizeof(line), f)) {
1089 if (startswith(l, field)) {
1091 l += strspn(l, WHITESPACE);
1093 l[strcspn(l, WHITESPACE)] = 0;
1095 r = parse_uid(l, uid);
1108 int get_process_uid(pid_t pid, uid_t *uid) {
1109 return get_process_id(pid, "Uid:", uid);
1112 int get_process_gid(pid_t pid, gid_t *gid) {
1113 return get_process_id(pid, "Gid:", gid);
1116 char *strnappend(const char *s, const char *suffix, size_t b) {
1124 return strndup(suffix, b);
1133 if (b > ((size_t) -1) - a)
1136 r = new(char, a+b+1);
1141 memcpy(r+a, suffix, b);
1147 char *strappend(const char *s, const char *suffix) {
1148 return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
1151 int readlink_malloc(const char *p, char **r) {
1161 if (!(c = new(char, l)))
1164 if ((n = readlink(p, c, l-1)) < 0) {
1170 if ((size_t) n < l-1) {
1181 int readlink_and_make_absolute(const char *p, char **r) {
1188 if ((j = readlink_malloc(p, &target)) < 0)
1191 k = file_in_same_dir(p, target);
1201 int readlink_and_canonicalize(const char *p, char **r) {
1208 j = readlink_and_make_absolute(p, &t);
1212 s = canonicalize_file_name(t);
1219 path_kill_slashes(*r);
1224 int reset_all_signal_handlers(void) {
1227 for (sig = 1; sig < _NSIG; sig++) {
1228 struct sigaction sa;
1230 if (sig == SIGKILL || sig == SIGSTOP)
1234 sa.sa_handler = SIG_DFL;
1235 sa.sa_flags = SA_RESTART;
1237 /* On Linux the first two RT signals are reserved by
1238 * glibc, and sigaction() will return EINVAL for them. */
1239 if ((sigaction(sig, &sa, NULL) < 0))
1240 if (errno != EINVAL)
1247 char *strstrip(char *s) {
1250 /* Drops trailing whitespace. Modifies the string in
1251 * place. Returns pointer to first non-space character */
1253 s += strspn(s, WHITESPACE);
1255 for (e = strchr(s, 0); e > s; e --)
1256 if (!strchr(WHITESPACE, e[-1]))
1264 char *delete_chars(char *s, const char *bad) {
1267 /* Drops all whitespace, regardless where in the string */
1269 for (f = s, t = s; *f; f++) {
1270 if (strchr(bad, *f))
1281 bool in_charset(const char *s, const char* charset) {
1287 for (i = s; *i; i++)
1288 if (!strchr(charset, *i))
1294 char *file_in_same_dir(const char *path, const char *filename) {
1301 /* This removes the last component of path and appends
1302 * filename, unless the latter is absolute anyway or the
1305 if (path_is_absolute(filename))
1306 return strdup(filename);
1308 if (!(e = strrchr(path, '/')))
1309 return strdup(filename);
1311 k = strlen(filename);
1312 if (!(r = new(char, e-path+1+k+1)))
1315 memcpy(r, path, e-path+1);
1316 memcpy(r+(e-path)+1, filename, k+1);
1321 int rmdir_parents(const char *path, const char *stop) {
1330 /* Skip trailing slashes */
1331 while (l > 0 && path[l-1] == '/')
1337 /* Skip last component */
1338 while (l > 0 && path[l-1] != '/')
1341 /* Skip trailing slashes */
1342 while (l > 0 && path[l-1] == '/')
1348 if (!(t = strndup(path, l)))
1351 if (path_startswith(stop, t)) {
1360 if (errno != ENOENT)
1368 char hexchar(int x) {
1369 static const char table[16] = "0123456789abcdef";
1371 return table[x & 15];
1374 int unhexchar(char c) {
1376 if (c >= '0' && c <= '9')
1379 if (c >= 'a' && c <= 'f')
1380 return c - 'a' + 10;
1382 if (c >= 'A' && c <= 'F')
1383 return c - 'A' + 10;
1388 char octchar(int x) {
1389 return '0' + (x & 7);
1392 int unoctchar(char c) {
1394 if (c >= '0' && c <= '7')
1400 char decchar(int x) {
1401 return '0' + (x % 10);
1404 int undecchar(char c) {
1406 if (c >= '0' && c <= '9')
1412 char *cescape(const char *s) {
1418 /* Does C style string escaping. */
1420 r = new(char, strlen(s)*4 + 1);
1424 for (f = s, t = r; *f; f++)
1470 /* For special chars we prefer octal over
1471 * hexadecimal encoding, simply because glib's
1472 * g_strescape() does the same */
1473 if ((*f < ' ') || (*f >= 127)) {
1475 *(t++) = octchar((unsigned char) *f >> 6);
1476 *(t++) = octchar((unsigned char) *f >> 3);
1477 *(t++) = octchar((unsigned char) *f);
1488 char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix) {
1495 /* Undoes C style string escaping, and optionally prefixes it. */
1497 pl = prefix ? strlen(prefix) : 0;
1499 r = new(char, pl+length+1);
1504 memcpy(r, prefix, pl);
1506 for (f = s, t = r + pl; f < s + length; f++) {
1549 /* This is an extension of the XDG syntax files */
1554 /* hexadecimal encoding */
1557 a = unhexchar(f[1]);
1558 b = unhexchar(f[2]);
1560 if (a < 0 || b < 0) {
1561 /* Invalid escape code, let's take it literal then */
1565 *(t++) = (char) ((a << 4) | b);
1580 /* octal encoding */
1583 a = unoctchar(f[0]);
1584 b = unoctchar(f[1]);
1585 c = unoctchar(f[2]);
1587 if (a < 0 || b < 0 || c < 0) {
1588 /* Invalid escape code, let's take it literal then */
1592 *(t++) = (char) ((a << 6) | (b << 3) | c);
1600 /* premature end of string.*/
1605 /* Invalid escape code, let's take it literal then */
1617 char *cunescape_length(const char *s, size_t length) {
1618 return cunescape_length_with_prefix(s, length, NULL);
1621 char *cunescape(const char *s) {
1624 return cunescape_length(s, strlen(s));
1627 char *xescape(const char *s, const char *bad) {
1631 /* Escapes all chars in bad, in addition to \ and all special
1632 * chars, in \xFF style escaping. May be reversed with
1635 r = new(char, strlen(s) * 4 + 1);
1639 for (f = s, t = r; *f; f++) {
1641 if ((*f < ' ') || (*f >= 127) ||
1642 (*f == '\\') || strchr(bad, *f)) {
1645 *(t++) = hexchar(*f >> 4);
1646 *(t++) = hexchar(*f);
1656 char *bus_path_escape(const char *s) {
1662 /* Escapes all chars that D-Bus' object path cannot deal
1663 * with. Can be reverse with bus_path_unescape() */
1665 if (!(r = new(char, strlen(s)*3+1)))
1668 for (f = s, t = r; *f; f++) {
1670 if (!(*f >= 'A' && *f <= 'Z') &&
1671 !(*f >= 'a' && *f <= 'z') &&
1672 !(*f >= '0' && *f <= '9')) {
1674 *(t++) = hexchar(*f >> 4);
1675 *(t++) = hexchar(*f);
1685 char *bus_path_unescape(const char *f) {
1690 if (!(r = strdup(f)))
1693 for (t = r; *f; f++) {
1698 if ((a = unhexchar(f[1])) < 0 ||
1699 (b = unhexchar(f[2])) < 0) {
1700 /* Invalid escape code, let's take it literal then */
1703 *(t++) = (char) ((a << 4) | b);
1715 char *ascii_strlower(char *t) {
1720 for (p = t; *p; p++)
1721 if (*p >= 'A' && *p <= 'Z')
1722 *p = *p - 'A' + 'a';
1727 static bool ignore_file_allow_backup(const char *filename) {
1731 filename[0] == '.' ||
1732 streq(filename, "lost+found") ||
1733 streq(filename, "aquota.user") ||
1734 streq(filename, "aquota.group") ||
1735 endswith(filename, ".rpmnew") ||
1736 endswith(filename, ".rpmsave") ||
1737 endswith(filename, ".rpmorig") ||
1738 endswith(filename, ".dpkg-old") ||
1739 endswith(filename, ".dpkg-new") ||
1740 endswith(filename, ".swp");
1743 bool ignore_file(const char *filename) {
1746 if (endswith(filename, "~"))
1749 return ignore_file_allow_backup(filename);
1752 int fd_nonblock(int fd, bool nonblock) {
1757 if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
1761 flags |= O_NONBLOCK;
1763 flags &= ~O_NONBLOCK;
1765 if (fcntl(fd, F_SETFL, flags) < 0)
1771 int fd_cloexec(int fd, bool cloexec) {
1776 if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
1780 flags |= FD_CLOEXEC;
1782 flags &= ~FD_CLOEXEC;
1784 if (fcntl(fd, F_SETFD, flags) < 0)
1790 static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
1793 assert(n_fdset == 0 || fdset);
1795 for (i = 0; i < n_fdset; i++)
1802 int close_all_fds(const int except[], unsigned n_except) {
1807 assert(n_except == 0 || except);
1809 d = opendir("/proc/self/fd");
1814 /* When /proc isn't available (for example in chroots)
1815 * the fallback is brute forcing through the fd
1818 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
1819 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
1821 if (fd_in_set(fd, except, n_except))
1824 if (close_nointr(fd) < 0)
1825 if (errno != EBADF && r == 0)
1832 while ((de = readdir(d))) {
1835 if (ignore_file(de->d_name))
1838 if (safe_atoi(de->d_name, &fd) < 0)
1839 /* Let's better ignore this, just in case */
1848 if (fd_in_set(fd, except, n_except))
1851 if (close_nointr(fd) < 0) {
1852 /* Valgrind has its own FD and doesn't want to have it closed */
1853 if (errno != EBADF && r == 0)
1862 bool chars_intersect(const char *a, const char *b) {
1865 /* Returns true if any of the chars in a are in b. */
1866 for (p = a; *p; p++)
1873 bool fstype_is_network(const char *fstype) {
1874 static const char table[] =
1883 return nulstr_contains(table, fstype);
1887 _cleanup_close_ int fd;
1889 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
1895 TIOCL_GETKMSGREDIRECT,
1899 if (ioctl(fd, TIOCLINUX, tiocl) < 0)
1902 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
1905 if (ioctl(fd, VT_ACTIVATE, vt) < 0)
1911 int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
1912 struct termios old_termios, new_termios;
1914 char line[LINE_MAX];
1919 if (tcgetattr(fileno(f), &old_termios) >= 0) {
1920 new_termios = old_termios;
1922 new_termios.c_lflag &= ~ICANON;
1923 new_termios.c_cc[VMIN] = 1;
1924 new_termios.c_cc[VTIME] = 0;
1926 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
1929 if (t != (usec_t) -1) {
1930 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
1931 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
1936 k = fread(&c, 1, 1, f);
1938 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
1944 *need_nl = c != '\n';
1951 if (t != (usec_t) -1)
1952 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
1955 if (!fgets(line, sizeof(line), f))
1960 if (strlen(line) != 1)
1970 int ask(char *ret, const char *replies, const char *text, ...) {
1980 bool need_nl = true;
1983 fputs(ANSI_HIGHLIGHT_ON, stdout);
1990 fputs(ANSI_HIGHLIGHT_OFF, stdout);
1994 r = read_one_char(stdin, &c, (usec_t) -1, &need_nl);
1997 if (r == -EBADMSG) {
1998 puts("Bad input, please try again.");
2009 if (strchr(replies, c)) {
2014 puts("Read unexpected character, please try again.");
2018 int reset_terminal_fd(int fd, bool switch_to_text) {
2019 struct termios termios;
2022 /* Set terminal to some sane defaults */
2026 /* We leave locked terminal attributes untouched, so that
2027 * Plymouth may set whatever it wants to set, and we don't
2028 * interfere with that. */
2030 /* Disable exclusive mode, just in case */
2031 ioctl(fd, TIOCNXCL);
2033 /* Switch to text mode */
2035 ioctl(fd, KDSETMODE, KD_TEXT);
2037 /* Enable console unicode mode */
2038 ioctl(fd, KDSKBMODE, K_UNICODE);
2040 if (tcgetattr(fd, &termios) < 0) {
2045 /* We only reset the stuff that matters to the software. How
2046 * hardware is set up we don't touch assuming that somebody
2047 * else will do that for us */
2049 termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
2050 termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
2051 termios.c_oflag |= ONLCR;
2052 termios.c_cflag |= CREAD;
2053 termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
2055 termios.c_cc[VINTR] = 03; /* ^C */
2056 termios.c_cc[VQUIT] = 034; /* ^\ */
2057 termios.c_cc[VERASE] = 0177;
2058 termios.c_cc[VKILL] = 025; /* ^X */
2059 termios.c_cc[VEOF] = 04; /* ^D */
2060 termios.c_cc[VSTART] = 021; /* ^Q */
2061 termios.c_cc[VSTOP] = 023; /* ^S */
2062 termios.c_cc[VSUSP] = 032; /* ^Z */
2063 termios.c_cc[VLNEXT] = 026; /* ^V */
2064 termios.c_cc[VWERASE] = 027; /* ^W */
2065 termios.c_cc[VREPRINT] = 022; /* ^R */
2066 termios.c_cc[VEOL] = 0;
2067 termios.c_cc[VEOL2] = 0;
2069 termios.c_cc[VTIME] = 0;
2070 termios.c_cc[VMIN] = 1;
2072 if (tcsetattr(fd, TCSANOW, &termios) < 0)
2076 /* Just in case, flush all crap out */
2077 tcflush(fd, TCIOFLUSH);
2082 int reset_terminal(const char *name) {
2085 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2089 r = reset_terminal_fd(fd, true);
2090 close_nointr_nofail(fd);
2095 int open_terminal(const char *name, int mode) {
2100 * If a TTY is in the process of being closed opening it might
2101 * cause EIO. This is horribly awful, but unlikely to be
2102 * changed in the kernel. Hence we work around this problem by
2103 * retrying a couple of times.
2105 * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
2109 fd = open(name, mode);
2116 /* Max 1s in total */
2120 usleep(50 * USEC_PER_MSEC);
2129 close_nointr_nofail(fd);
2134 close_nointr_nofail(fd);
2141 int flush_fd(int fd) {
2142 struct pollfd pollfd;
2146 pollfd.events = POLLIN;
2153 if ((r = poll(&pollfd, 1, 0)) < 0) {
2164 if ((l = read(fd, buf, sizeof(buf))) < 0) {
2169 if (errno == EAGAIN)
2180 int acquire_terminal(
2184 bool ignore_tiocstty_eperm,
2187 int fd = -1, notify = -1, r = 0, wd = -1;
2189 struct sigaction sa_old, sa_new;
2193 /* We use inotify to be notified when the tty is closed. We
2194 * create the watch before checking if we can actually acquire
2195 * it, so that we don't lose any event.
2197 * Note: strictly speaking this actually watches for the
2198 * device being closed, it does *not* really watch whether a
2199 * tty loses its controlling process. However, unless some
2200 * rogue process uses TIOCNOTTY on /dev/tty *after* closing
2201 * its tty otherwise this will not become a problem. As long
2202 * as the administrator makes sure not configure any service
2203 * on the same tty as an untrusted user this should not be a
2204 * problem. (Which he probably should not do anyway.) */
2206 if (timeout != (usec_t) -1)
2207 ts = now(CLOCK_MONOTONIC);
2209 if (!fail && !force) {
2210 notify = inotify_init1(IN_CLOEXEC | (timeout != (usec_t) -1 ? IN_NONBLOCK : 0));
2216 wd = inotify_add_watch(notify, name, IN_CLOSE);
2225 r = flush_fd(notify);
2230 /* We pass here O_NOCTTY only so that we can check the return
2231 * value TIOCSCTTY and have a reliable way to figure out if we
2232 * successfully became the controlling process of the tty */
2233 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2237 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2238 * if we already own the tty. */
2240 sa_new.sa_handler = SIG_IGN;
2241 sa_new.sa_flags = SA_RESTART;
2242 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2244 /* First, try to get the tty */
2245 if (ioctl(fd, TIOCSCTTY, force) < 0)
2248 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2250 /* Sometimes it makes sense to ignore TIOCSCTTY
2251 * returning EPERM, i.e. when very likely we already
2252 * are have this controlling terminal. */
2253 if (r < 0 && r == -EPERM && ignore_tiocstty_eperm)
2256 if (r < 0 && (force || fail || r != -EPERM)) {
2265 assert(notify >= 0);
2268 uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
2270 struct inotify_event *e;
2272 if (timeout != (usec_t) -1) {
2275 n = now(CLOCK_MONOTONIC);
2276 if (ts + timeout < n) {
2281 r = fd_wait_for_event(fd, POLLIN, ts + timeout - n);
2291 l = read(notify, inotify_buffer, sizeof(inotify_buffer));
2294 if (errno == EINTR || errno == EAGAIN)
2301 e = (struct inotify_event*) inotify_buffer;
2306 if (e->wd != wd || !(e->mask & IN_CLOSE)) {
2311 step = sizeof(struct inotify_event) + e->len;
2312 assert(step <= (size_t) l);
2314 e = (struct inotify_event*) ((uint8_t*) e + step);
2321 /* We close the tty fd here since if the old session
2322 * ended our handle will be dead. It's important that
2323 * we do this after sleeping, so that we don't enter
2324 * an endless loop. */
2325 close_nointr_nofail(fd);
2329 close_nointr_nofail(notify);
2331 r = reset_terminal_fd(fd, true);
2333 log_warning("Failed to reset terminal: %s", strerror(-r));
2339 close_nointr_nofail(fd);
2342 close_nointr_nofail(notify);
2347 int release_terminal(void) {
2349 struct sigaction sa_old, sa_new;
2351 if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC)) < 0)
2354 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2355 * by our own TIOCNOTTY */
2358 sa_new.sa_handler = SIG_IGN;
2359 sa_new.sa_flags = SA_RESTART;
2360 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2362 if (ioctl(fd, TIOCNOTTY) < 0)
2365 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2367 close_nointr_nofail(fd);
2371 int sigaction_many(const struct sigaction *sa, ...) {
2376 while ((sig = va_arg(ap, int)) > 0)
2377 if (sigaction(sig, sa, NULL) < 0)
2384 int ignore_signals(int sig, ...) {
2385 struct sigaction sa;
2390 sa.sa_handler = SIG_IGN;
2391 sa.sa_flags = SA_RESTART;
2393 if (sigaction(sig, &sa, NULL) < 0)
2397 while ((sig = va_arg(ap, int)) > 0)
2398 if (sigaction(sig, &sa, NULL) < 0)
2405 int default_signals(int sig, ...) {
2406 struct sigaction sa;
2411 sa.sa_handler = SIG_DFL;
2412 sa.sa_flags = SA_RESTART;
2414 if (sigaction(sig, &sa, NULL) < 0)
2418 while ((sig = va_arg(ap, int)) > 0)
2419 if (sigaction(sig, &sa, NULL) < 0)
2426 int close_pipe(int p[]) {
2432 a = close_nointr(p[0]);
2437 b = close_nointr(p[1]);
2441 return a < 0 ? a : b;
2444 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2453 while (nbytes > 0) {
2456 if ((k = read(fd, p, nbytes)) <= 0) {
2458 if (k < 0 && errno == EINTR)
2461 if (k < 0 && errno == EAGAIN && do_poll) {
2462 struct pollfd pollfd;
2466 pollfd.events = POLLIN;
2468 if (poll(&pollfd, 1, -1) < 0) {
2472 return n > 0 ? n : -errno;
2475 if (pollfd.revents != POLLIN)
2476 return n > 0 ? n : -EIO;
2481 return n > 0 ? n : (k < 0 ? -errno : 0);
2492 ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2501 while (nbytes > 0) {
2504 k = write(fd, p, nbytes);
2507 if (k < 0 && errno == EINTR)
2510 if (k < 0 && errno == EAGAIN && do_poll) {
2511 struct pollfd pollfd;
2515 pollfd.events = POLLOUT;
2517 if (poll(&pollfd, 1, -1) < 0) {
2521 return n > 0 ? n : -errno;
2524 if (pollfd.revents != POLLOUT)
2525 return n > 0 ? n : -EIO;
2530 return n > 0 ? n : (k < 0 ? -errno : 0);
2541 int parse_bytes(const char *t, off_t *bytes) {
2542 static const struct {
2548 { "M", 1024ULL*1024ULL },
2549 { "G", 1024ULL*1024ULL*1024ULL },
2550 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2551 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2552 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2569 l = strtoll(p, &e, 10);
2580 e += strspn(e, WHITESPACE);
2582 for (i = 0; i < ELEMENTSOF(table); i++)
2583 if (startswith(e, table[i].suffix)) {
2584 r += (off_t) l * table[i].factor;
2585 p = e + strlen(table[i].suffix);
2589 if (i >= ELEMENTSOF(table))
2599 int make_stdio(int fd) {
2604 r = dup3(fd, STDIN_FILENO, 0);
2605 s = dup3(fd, STDOUT_FILENO, 0);
2606 t = dup3(fd, STDERR_FILENO, 0);
2609 close_nointr_nofail(fd);
2611 if (r < 0 || s < 0 || t < 0)
2614 /* We rely here that the new fd has O_CLOEXEC not set */
2619 int make_null_stdio(void) {
2622 null_fd = open("/dev/null", O_RDWR|O_NOCTTY);
2626 return make_stdio(null_fd);
2629 bool is_device_path(const char *path) {
2631 /* Returns true on paths that refer to a device, either in
2632 * sysfs or in /dev */
2635 path_startswith(path, "/dev/") ||
2636 path_startswith(path, "/sys/");
2639 int dir_is_empty(const char *path) {
2640 _cleanup_closedir_ DIR *d;
2649 union dirent_storage buf;
2651 r = readdir_r(d, &buf.de, &de);
2658 if (!ignore_file(de->d_name))
2663 unsigned long long random_ull(void) {
2664 _cleanup_close_ int fd;
2668 fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
2672 r = loop_read(fd, &ull, sizeof(ull), true);
2673 if (r != sizeof(ull))
2679 return random() * RAND_MAX + random();
2682 void rename_process(const char name[8]) {
2685 /* This is a like a poor man's setproctitle(). It changes the
2686 * comm field, argv[0], and also the glibc's internally used
2687 * name of the process. For the first one a limit of 16 chars
2688 * applies, to the second one usually one of 10 (i.e. length
2689 * of "/sbin/init"), to the third one one of 7 (i.e. length of
2690 * "systemd"). If you pass a longer string it will be
2693 prctl(PR_SET_NAME, name);
2695 if (program_invocation_name)
2696 strncpy(program_invocation_name, name, strlen(program_invocation_name));
2698 if (saved_argc > 0) {
2702 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
2704 for (i = 1; i < saved_argc; i++) {
2708 memset(saved_argv[i], 0, strlen(saved_argv[i]));
2713 void sigset_add_many(sigset_t *ss, ...) {
2720 while ((sig = va_arg(ap, int)) > 0)
2721 assert_se(sigaddset(ss, sig) == 0);
2725 char* gethostname_malloc(void) {
2728 assert_se(uname(&u) >= 0);
2730 if (!isempty(u.nodename) && !streq(u.nodename, "(none)"))
2731 return strdup(u.nodename);
2733 return strdup(u.sysname);
2736 bool hostname_is_set(void) {
2739 assert_se(uname(&u) >= 0);
2741 return !isempty(u.nodename) && !streq(u.nodename, "(none)");
2744 static char *lookup_uid(uid_t uid) {
2747 _cleanup_free_ char *buf = NULL;
2748 struct passwd pwbuf, *pw = NULL;
2750 /* Shortcut things to avoid NSS lookups */
2752 return strdup("root");
2754 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
2758 buf = malloc(bufsize);
2762 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
2763 return strdup(pw->pw_name);
2765 if (asprintf(&name, "%lu", (unsigned long) uid) < 0)
2771 char* getlogname_malloc(void) {
2775 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
2780 return lookup_uid(uid);
2783 char *getusername_malloc(void) {
2790 return lookup_uid(getuid());
2793 int getttyname_malloc(int fd, char **r) {
2794 char path[PATH_MAX], *c;
2799 k = ttyname_r(fd, path, sizeof(path));
2805 c = strdup(startswith(path, "/dev/") ? path + 5 : path);
2813 int getttyname_harder(int fd, char **r) {
2817 k = getttyname_malloc(fd, &s);
2821 if (streq(s, "tty")) {
2823 return get_ctty(0, NULL, r);
2830 int get_ctty_devnr(pid_t pid, dev_t *d) {
2832 char line[LINE_MAX], *p, *fn;
2833 unsigned long ttynr;
2836 if (asprintf(&fn, "/proc/%lu/stat", (unsigned long) (pid <= 0 ? getpid() : pid)) < 0)
2839 f = fopen(fn, "re");
2844 if (!fgets(line, sizeof(line), f)) {
2845 k = feof(f) ? -EIO : -errno;
2852 p = strrchr(line, ')');
2862 "%*d " /* session */
2867 if (major(ttynr) == 0 && minor(ttynr) == 0)
2874 int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
2876 char fn[PATH_MAX], *s, *b, *p;
2881 k = get_ctty_devnr(pid, &devnr);
2885 snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
2888 k = readlink_malloc(fn, &s);
2894 /* This is an ugly hack */
2895 if (major(devnr) == 136) {
2896 if (asprintf(&b, "pts/%lu", (unsigned long) minor(devnr)) < 0)
2906 /* Probably something like the ptys which have no
2907 * symlink in /dev/char. Let's return something
2908 * vaguely useful. */
2921 if (startswith(s, "/dev/"))
2923 else if (startswith(s, "../"))
2941 int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
2947 /* This returns the first error we run into, but nevertheless
2948 * tries to go on. This closes the passed fd. */
2952 close_nointr_nofail(fd);
2954 return errno == ENOENT ? 0 : -errno;
2959 union dirent_storage buf;
2960 bool is_dir, keep_around;
2964 r = readdir_r(d, &buf.de, &de);
2965 if (r != 0 && ret == 0) {
2973 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
2976 if (de->d_type == DT_UNKNOWN ||
2978 (de->d_type == DT_DIR && root_dev)) {
2979 if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
2980 if (ret == 0 && errno != ENOENT)
2985 is_dir = S_ISDIR(st.st_mode);
2988 (st.st_uid == 0 || st.st_uid == getuid()) &&
2989 (st.st_mode & S_ISVTX);
2991 is_dir = de->d_type == DT_DIR;
2992 keep_around = false;
2998 /* if root_dev is set, remove subdirectories only, if device is same as dir */
2999 if (root_dev && st.st_dev != root_dev->st_dev)
3002 subdir_fd = openat(fd, de->d_name,
3003 O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3004 if (subdir_fd < 0) {
3005 if (ret == 0 && errno != ENOENT)
3010 r = rm_rf_children_dangerous(subdir_fd, only_dirs, honour_sticky, root_dev);
3011 if (r < 0 && ret == 0)
3015 if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
3016 if (ret == 0 && errno != ENOENT)
3020 } else if (!only_dirs && !keep_around) {
3022 if (unlinkat(fd, de->d_name, 0) < 0) {
3023 if (ret == 0 && errno != ENOENT)
3034 static int is_temporary_fs(struct statfs *s) {
3036 return s->f_type == TMPFS_MAGIC ||
3037 (long)s->f_type == (long)RAMFS_MAGIC;
3040 int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
3045 if (fstatfs(fd, &s) < 0) {
3046 close_nointr_nofail(fd);
3050 /* We refuse to clean disk file systems with this call. This
3051 * is extra paranoia just to be sure we never ever remove
3053 if (!is_temporary_fs(&s)) {
3054 log_error("Attempted to remove disk file system, and we can't allow that.");
3055 close_nointr_nofail(fd);
3059 return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev);
3062 static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
3068 /* We refuse to clean the root file system with this
3069 * call. This is extra paranoia to never cause a really
3070 * seriously broken system. */
3071 if (path_equal(path, "/")) {
3072 log_error("Attempted to remove entire root file system, and we can't allow that.");
3076 fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3079 if (errno != ENOTDIR)
3083 if (statfs(path, &s) < 0)
3086 if (!is_temporary_fs(&s)) {
3087 log_error("Attempted to remove disk file system, and we can't allow that.");
3092 if (delete_root && !only_dirs)
3093 if (unlink(path) < 0 && errno != ENOENT)
3100 if (fstatfs(fd, &s) < 0) {
3101 close_nointr_nofail(fd);
3105 if (!is_temporary_fs(&s)) {
3106 log_error("Attempted to remove disk file system, and we can't allow that.");
3107 close_nointr_nofail(fd);
3112 r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL);
3115 if (honour_sticky && file_is_priv_sticky(path) > 0)
3118 if (rmdir(path) < 0 && errno != ENOENT) {
3127 int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3128 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false);
3131 int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3132 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, true);
3135 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
3138 /* Under the assumption that we are running privileged we
3139 * first change the access mode and only then hand out
3140 * ownership to avoid a window where access is too open. */
3142 if (mode != (mode_t) -1)
3143 if (chmod(path, mode) < 0)
3146 if (uid != (uid_t) -1 || gid != (gid_t) -1)
3147 if (chown(path, uid, gid) < 0)
3153 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
3156 /* Under the assumption that we are running privileged we
3157 * first change the access mode and only then hand out
3158 * ownership to avoid a window where access is too open. */
3160 if (fchmod(fd, mode) < 0)
3163 if (fchown(fd, uid, gid) < 0)
3169 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
3173 /* Allocates the cpuset in the right size */
3176 if (!(r = CPU_ALLOC(n)))
3179 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
3180 CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
3190 if (errno != EINVAL)
3197 int status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) {
3198 static const char status_indent[] = " "; /* "[" STATUS "] " */
3199 _cleanup_free_ char *s = NULL;
3200 _cleanup_close_ int fd = -1;
3201 struct iovec iovec[5];
3206 /* This is independent of logging, as status messages are
3207 * optional and go exclusively to the console. */
3209 if (vasprintf(&s, format, ap) < 0)
3212 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
3225 sl = status ? sizeof(status_indent)-1 : 0;
3231 e = ellipsize(s, emax, 75);
3241 if (!isempty(status)) {
3242 IOVEC_SET_STRING(iovec[n++], "[");
3243 IOVEC_SET_STRING(iovec[n++], status);
3244 IOVEC_SET_STRING(iovec[n++], "] ");
3246 IOVEC_SET_STRING(iovec[n++], status_indent);
3249 IOVEC_SET_STRING(iovec[n++], s);
3250 IOVEC_SET_STRING(iovec[n++], "\n");
3252 if (writev(fd, iovec, n) < 0)
3258 int status_printf(const char *status, bool ellipse, const char *format, ...) {
3264 va_start(ap, format);
3265 r = status_vprintf(status, ellipse, format, ap);
3271 int status_welcome(void) {
3273 _cleanup_free_ char *pretty_name = NULL, *ansi_color = NULL;
3275 r = parse_env_file("/etc/os-release", NEWLINE,
3276 "PRETTY_NAME", &pretty_name,
3277 "ANSI_COLOR", &ansi_color,
3279 if (r < 0 && r != -ENOENT)
3280 log_warning("Failed to read /etc/os-release: %s", strerror(-r));
3282 return status_printf(NULL, false,
3283 "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
3284 isempty(ansi_color) ? "1" : ansi_color,
3285 isempty(pretty_name) ? "Linux" : pretty_name);
3288 char *replace_env(const char *format, char **env) {
3295 const char *e, *word = format;
3300 for (e = format; *e; e ++) {
3311 if (!(k = strnappend(r, word, e-word-1)))
3320 } else if (*e == '$') {
3321 if (!(k = strnappend(r, word, e-word)))
3337 if (!(t = strv_env_get_with_length(env, word+2, e-word-2)))
3340 if (!(k = strappend(r, t)))
3353 if (!(k = strnappend(r, word, e-word)))
3364 char **replace_env_argv(char **argv, char **env) {
3366 unsigned k = 0, l = 0;
3368 l = strv_length(argv);
3370 if (!(r = new(char*, l+1)))
3373 STRV_FOREACH(i, argv) {
3375 /* If $FOO appears as single word, replace it by the split up variable */
3376 if ((*i)[0] == '$' && (*i)[1] != '{') {
3381 if ((e = strv_env_get(env, *i+1))) {
3383 if (!(m = strv_split_quoted(e))) {
3394 if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
3403 memcpy(r + k, m, q * sizeof(char*));
3411 /* If ${FOO} appears as part of a word, replace it by the variable as-is */
3412 if (!(r[k++] = replace_env(*i, env))) {
3422 int fd_columns(int fd) {
3426 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3435 unsigned columns(void) {
3439 if (_likely_(cached_columns > 0))
3440 return cached_columns;
3443 e = getenv("COLUMNS");
3448 c = fd_columns(STDOUT_FILENO);
3457 int fd_lines(int fd) {
3461 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3470 unsigned lines(void) {
3474 if (_likely_(cached_lines > 0))
3475 return cached_lines;
3478 e = getenv("LINES");
3483 l = fd_lines(STDOUT_FILENO);
3489 return cached_lines;
3492 /* intended to be used as a SIGWINCH sighandler */
3493 void columns_lines_cache_reset(int signum) {
3499 static int cached_on_tty = -1;
3501 if (_unlikely_(cached_on_tty < 0))
3502 cached_on_tty = isatty(STDOUT_FILENO) > 0;
3504 return cached_on_tty;
3507 int running_in_chroot(void) {
3513 /* Only works as root */
3515 if (stat("/proc/1/root", &a) < 0)
3518 if (stat("/", &b) < 0)
3522 a.st_dev != b.st_dev ||
3523 a.st_ino != b.st_ino;
3526 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
3531 assert(percent <= 100);
3532 assert(new_length >= 3);
3534 if (old_length <= 3 || old_length <= new_length)
3535 return strndup(s, old_length);
3537 r = new0(char, new_length+1);
3541 x = (new_length * percent) / 100;
3543 if (x > new_length - 3)
3551 s + old_length - (new_length - x - 3),
3552 new_length - x - 3);
3557 char *ellipsize(const char *s, size_t length, unsigned percent) {
3558 return ellipsize_mem(s, strlen(s), length, percent);
3561 int touch(const char *path) {
3566 /* This just opens the file for writing, ensuring it
3567 * exists. It doesn't call utimensat() the way /usr/bin/touch
3570 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644);
3574 close_nointr_nofail(fd);
3578 char *unquote(const char *s, const char* quotes) {
3582 /* This is rather stupid, simply removes the heading and
3583 * trailing quotes if there is one. Doesn't care about
3584 * escaping or anything. We should make this smarter one
3591 if (strchr(quotes, s[0]) && s[l-1] == s[0])
3592 return strndup(s+1, l-2);
3597 char *normalize_env_assignment(const char *s) {
3598 _cleanup_free_ char *name = NULL, *value = NULL, *p = NULL;
3601 eq = strchr(s, '=');
3613 memmove(r, t, strlen(t) + 1);
3617 name = strndup(s, eq - s);
3625 value = unquote(strstrip(p), QUOTES);
3629 if (asprintf(&r, "%s=%s", strstrip(name), value) < 0)
3635 int wait_for_terminate(pid_t pid, siginfo_t *status) {
3646 if (waitid(P_PID, pid, status, WEXITED) < 0) {
3658 int wait_for_terminate_and_warn(const char *name, pid_t pid) {
3665 r = wait_for_terminate(pid, &status);
3667 log_warning("Failed to wait for %s: %s", name, strerror(-r));
3671 if (status.si_code == CLD_EXITED) {
3672 if (status.si_status != 0) {
3673 log_warning("%s failed with error code %i.", name, status.si_status);
3674 return status.si_status;
3677 log_debug("%s succeeded.", name);
3680 } else if (status.si_code == CLD_KILLED ||
3681 status.si_code == CLD_DUMPED) {
3683 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
3687 log_warning("%s failed due to unknown reason.", name);
3691 _noreturn_ void freeze(void) {
3693 /* Make sure nobody waits for us on a socket anymore */
3694 close_all_fds(NULL, 0);
3702 bool null_or_empty(struct stat *st) {
3705 if (S_ISREG(st->st_mode) && st->st_size <= 0)
3708 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
3714 int null_or_empty_path(const char *fn) {
3719 if (stat(fn, &st) < 0)
3722 return null_or_empty(&st);
3725 DIR *xopendirat(int fd, const char *name, int flags) {
3729 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags);
3735 close_nointr_nofail(nfd);
3742 int signal_from_string_try_harder(const char *s) {
3746 signo = signal_from_string(s);
3748 if (startswith(s, "SIG"))
3749 return signal_from_string(s+3);
3754 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
3758 /* FIXME: to follow udev's logic 100% we need to leave valid
3759 * UTF8 chars unescaped */
3761 u = unquote(tagvalue, "\"\'");
3765 t = xescape(u, "/ ");
3771 r = asprintf(&dn, "/dev/disk/by-%s/%s", by, t);
3780 char *fstab_node_to_udev_node(const char *p) {
3783 if (startswith(p, "LABEL="))
3784 return tag_to_udev_node(p+6, "label");
3786 if (startswith(p, "UUID="))
3787 return tag_to_udev_node(p+5, "uuid");
3789 if (startswith(p, "PARTUUID="))
3790 return tag_to_udev_node(p+9, "partuuid");
3792 if (startswith(p, "PARTLABEL="))
3793 return tag_to_udev_node(p+10, "partlabel");
3798 bool tty_is_vc(const char *tty) {
3801 if (startswith(tty, "/dev/"))
3804 return vtnr_from_tty(tty) >= 0;
3807 bool tty_is_console(const char *tty) {
3810 if (startswith(tty, "/dev/"))
3813 return streq(tty, "console");
3816 int vtnr_from_tty(const char *tty) {
3821 if (startswith(tty, "/dev/"))
3824 if (!startswith(tty, "tty") )
3827 if (tty[3] < '0' || tty[3] > '9')
3830 r = safe_atoi(tty+3, &i);
3834 if (i < 0 || i > 63)
3840 bool tty_is_vc_resolve(const char *tty) {
3841 char *active = NULL;
3846 if (startswith(tty, "/dev/"))
3849 /* Resolve where /dev/console is pointing to, if /sys is
3850 * actually ours (i.e. not read-only-mounted which is a sign
3851 * for container setups) */
3852 if (streq(tty, "console") && path_is_read_only_fs("/sys") <= 0)
3853 if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) {
3854 /* If multiple log outputs are configured the
3855 * last one is what /dev/console points to */
3856 tty = strrchr(active, ' ');
3869 const char *default_term_for_tty(const char *tty) {
3872 return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102";
3875 bool dirent_is_file(const struct dirent *de) {
3878 if (ignore_file(de->d_name))
3881 if (de->d_type != DT_REG &&
3882 de->d_type != DT_LNK &&
3883 de->d_type != DT_UNKNOWN)
3889 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
3892 if (de->d_type != DT_REG &&
3893 de->d_type != DT_LNK &&
3894 de->d_type != DT_UNKNOWN)
3897 if (ignore_file_allow_backup(de->d_name))
3900 return endswith(de->d_name, suffix);
3903 void execute_directory(const char *directory, DIR *d, char *argv[]) {
3906 Hashmap *pids = NULL;
3910 /* Executes all binaries in a directory in parallel and waits
3911 * until all they all finished. */
3914 if (!(_d = opendir(directory))) {
3916 if (errno == ENOENT)
3919 log_error("Failed to enumerate directory %s: %m", directory);
3926 if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) {
3927 log_error("Failed to allocate set.");
3931 while ((de = readdir(d))) {
3936 if (!dirent_is_file(de))
3939 if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
3944 if ((pid = fork()) < 0) {
3945 log_error("Failed to fork: %m");
3963 log_error("Failed to execute %s: %m", path);
3964 _exit(EXIT_FAILURE);
3967 log_debug("Spawned %s as %lu", path, (unsigned long) pid);
3969 if ((k = hashmap_put(pids, UINT_TO_PTR(pid), path)) < 0) {
3970 log_error("Failed to add PID to set: %s", strerror(-k));
3975 while (!hashmap_isempty(pids)) {
3976 pid_t pid = PTR_TO_UINT(hashmap_first_key(pids));
3981 if (waitid(P_PID, pid, &si, WEXITED) < 0) {
3986 log_error("waitid() failed: %m");
3990 if ((path = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) {
3991 if (!is_clean_exit(si.si_code, si.si_status, NULL)) {
3992 if (si.si_code == CLD_EXITED)
3993 log_error("%s exited with exit status %i.", path, si.si_status);
3995 log_error("%s terminated by signal %s.", path, signal_to_string(si.si_status));
3997 log_debug("%s exited successfully.", path);
4008 hashmap_free_free(pids);
4011 int kill_and_sigcont(pid_t pid, int sig) {
4014 r = kill(pid, sig) < 0 ? -errno : 0;
4022 bool nulstr_contains(const char*nulstr, const char *needle) {
4028 NULSTR_FOREACH(i, nulstr)
4029 if (streq(i, needle))
4035 bool plymouth_running(void) {
4036 return access("/run/plymouth/pid", F_OK) >= 0;
4039 char* strshorten(char *s, size_t l) {
4048 static bool hostname_valid_char(char c) {
4050 (c >= 'a' && c <= 'z') ||
4051 (c >= 'A' && c <= 'Z') ||
4052 (c >= '0' && c <= '9') ||
4058 bool hostname_is_valid(const char *s) {
4064 for (p = s; *p; p++)
4065 if (!hostname_valid_char(*p))
4068 if (p-s > HOST_NAME_MAX)
4074 char* hostname_cleanup(char *s) {
4077 for (p = s, d = s; *p; p++)
4078 if ((*p >= 'a' && *p <= 'z') ||
4079 (*p >= 'A' && *p <= 'Z') ||
4080 (*p >= '0' && *p <= '9') ||
4088 strshorten(s, HOST_NAME_MAX);
4092 int pipe_eof(int fd) {
4093 struct pollfd pollfd;
4098 pollfd.events = POLLIN|POLLHUP;
4100 r = poll(&pollfd, 1, 0);
4107 return pollfd.revents & POLLHUP;
4110 int fd_wait_for_event(int fd, int event, usec_t t) {
4111 struct pollfd pollfd;
4116 pollfd.events = event;
4118 r = poll(&pollfd, 1, t == (usec_t) -1 ? -1 : (int) (t / USEC_PER_MSEC));
4125 return pollfd.revents;
4128 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
4139 t = new(char, strlen(path) + 1 + 6 + 1);
4143 fn = path_get_file_name(path);
4147 stpcpy(stpcpy(t+k+1, fn), "XXXXXX");
4149 fd = mkostemp(t, O_WRONLY|O_CLOEXEC);
4155 f = fdopen(fd, "we");
4168 int terminal_vhangup_fd(int fd) {
4171 if (ioctl(fd, TIOCVHANGUP) < 0)
4177 int terminal_vhangup(const char *name) {
4180 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4184 r = terminal_vhangup_fd(fd);
4185 close_nointr_nofail(fd);
4190 int vt_disallocate(const char *name) {
4194 /* Deallocate the VT if possible. If not possible
4195 * (i.e. because it is the active one), at least clear it
4196 * entirely (including the scrollback buffer) */
4198 if (!startswith(name, "/dev/"))
4201 if (!tty_is_vc(name)) {
4202 /* So this is not a VT. I guess we cannot deallocate
4203 * it then. But let's at least clear the screen */
4205 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4210 "\033[r" /* clear scrolling region */
4211 "\033[H" /* move home */
4212 "\033[2J", /* clear screen */
4214 close_nointr_nofail(fd);
4219 if (!startswith(name, "/dev/tty"))
4222 r = safe_atou(name+8, &u);
4229 /* Try to deallocate */
4230 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
4234 r = ioctl(fd, VT_DISALLOCATE, u);
4235 close_nointr_nofail(fd);
4243 /* Couldn't deallocate, so let's clear it fully with
4245 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4250 "\033[r" /* clear scrolling region */
4251 "\033[H" /* move home */
4252 "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
4254 close_nointr_nofail(fd);
4259 int copy_file(const char *from, const char *to) {
4265 fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
4269 fdt = open(to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY, 0644);
4271 close_nointr_nofail(fdf);
4279 n = read(fdf, buf, sizeof(buf));
4283 close_nointr_nofail(fdf);
4294 k = loop_write(fdt, buf, n, false);
4296 r = k < 0 ? k : (errno ? -errno : -EIO);
4298 close_nointr_nofail(fdf);
4306 close_nointr_nofail(fdf);
4307 r = close_nointr(fdt);
4317 int symlink_atomic(const char *from, const char *to) {
4319 _cleanup_free_ char *t;
4322 unsigned long long ull;
4329 t = new(char, strlen(to) + 1 + 16 + 1);
4333 fn = path_get_file_name(to);
4337 x = stpcpy(t+k+1, fn);
4340 for (i = 0; i < 16; i++) {
4341 *(x++) = hexchar(ull & 0xF);
4347 if (symlink(from, t) < 0)
4350 if (rename(t, to) < 0) {
4359 bool display_is_local(const char *display) {
4363 display[0] == ':' &&
4364 display[1] >= '0' &&
4368 int socket_from_display(const char *display, char **path) {
4375 if (!display_is_local(display))
4378 k = strspn(display+1, "0123456789");
4380 f = new(char, sizeof("/tmp/.X11-unix/X") + k);
4384 c = stpcpy(f, "/tmp/.X11-unix/X");
4385 memcpy(c, display+1, k);
4394 const char **username,
4395 uid_t *uid, gid_t *gid,
4397 const char **shell) {
4405 /* We enforce some special rules for uid=0: in order to avoid
4406 * NSS lookups for root we hardcode its data. */
4408 if (streq(*username, "root") || streq(*username, "0")) {
4426 if (parse_uid(*username, &u) >= 0) {
4430 /* If there are multiple users with the same id, make
4431 * sure to leave $USER to the configured value instead
4432 * of the first occurrence in the database. However if
4433 * the uid was configured by a numeric uid, then let's
4434 * pick the real username from /etc/passwd. */
4436 *username = p->pw_name;
4439 p = getpwnam(*username);
4443 return errno != 0 ? -errno : -ESRCH;
4455 *shell = p->pw_shell;
4460 char* uid_to_name(uid_t uid) {
4465 return strdup("root");
4469 return strdup(p->pw_name);
4471 if (asprintf(&r, "%lu", (unsigned long) uid) < 0)
4477 int get_group_creds(const char **groupname, gid_t *gid) {
4483 /* We enforce some special rules for gid=0: in order to avoid
4484 * NSS lookups for root we hardcode its data. */
4486 if (streq(*groupname, "root") || streq(*groupname, "0")) {
4487 *groupname = "root";
4495 if (parse_gid(*groupname, &id) >= 0) {
4500 *groupname = g->gr_name;
4503 g = getgrnam(*groupname);
4507 return errno != 0 ? -errno : -ESRCH;
4515 int in_group(const char *name) {
4517 int ngroups_max, r, i;
4519 r = get_group_creds(&name, &gid);
4523 if (getgid() == gid)
4526 if (getegid() == gid)
4529 ngroups_max = sysconf(_SC_NGROUPS_MAX);
4530 assert(ngroups_max > 0);
4532 gids = alloca(sizeof(gid_t) * ngroups_max);
4534 r = getgroups(ngroups_max, gids);
4538 for (i = 0; i < r; i++)
4545 int glob_exists(const char *path) {
4553 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
4555 if (k == GLOB_NOMATCH)
4557 else if (k == GLOB_NOSPACE)
4560 r = !strv_isempty(g.gl_pathv);
4562 r = errno ? -errno : -EIO;
4569 int dirent_ensure_type(DIR *d, struct dirent *de) {
4575 if (de->d_type != DT_UNKNOWN)
4578 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
4582 S_ISREG(st.st_mode) ? DT_REG :
4583 S_ISDIR(st.st_mode) ? DT_DIR :
4584 S_ISLNK(st.st_mode) ? DT_LNK :
4585 S_ISFIFO(st.st_mode) ? DT_FIFO :
4586 S_ISSOCK(st.st_mode) ? DT_SOCK :
4587 S_ISCHR(st.st_mode) ? DT_CHR :
4588 S_ISBLK(st.st_mode) ? DT_BLK :
4594 int in_search_path(const char *path, char **search) {
4598 r = path_get_parent(path, &parent);
4604 STRV_FOREACH(i, search) {
4605 if (path_equal(parent, *i)) {
4616 int get_files_in_directory(const char *path, char ***list) {
4624 /* Returns all files in a directory in *list, and the number
4625 * of files as return value. If list is NULL returns only the
4634 union dirent_storage buf;
4637 k = readdir_r(d, &buf.de, &de);
4646 dirent_ensure_type(d, de);
4648 if (!dirent_is_file(de))
4652 if ((unsigned) r >= n) {
4656 t = realloc(l, sizeof(char*) * n);
4665 assert((unsigned) r < n);
4667 l[r] = strdup(de->d_name);
4691 char *strjoin(const char *x, ...) {
4705 t = va_arg(ap, const char *);
4710 if (n > ((size_t) -1) - l) {
4734 t = va_arg(ap, const char *);
4748 bool is_main_thread(void) {
4749 static __thread int cached = 0;
4751 if (_unlikely_(cached == 0))
4752 cached = getpid() == gettid() ? 1 : -1;
4757 int block_get_whole_disk(dev_t d, dev_t *ret) {
4764 /* If it has a queue this is good enough for us */
4765 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
4768 r = access(p, F_OK);
4776 /* If it is a partition find the originating device */
4777 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
4780 r = access(p, F_OK);
4786 /* Get parent dev_t */
4787 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
4790 r = read_one_line_file(p, &s);
4796 r = sscanf(s, "%u:%u", &m, &n);
4802 /* Only return this if it is really good enough for us. */
4803 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
4806 r = access(p, F_OK);
4810 *ret = makedev(m, n);
4817 int file_is_priv_sticky(const char *p) {
4822 if (lstat(p, &st) < 0)
4826 (st.st_uid == 0 || st.st_uid == getuid()) &&
4827 (st.st_mode & S_ISVTX);
4830 static const char *const ioprio_class_table[] = {
4831 [IOPRIO_CLASS_NONE] = "none",
4832 [IOPRIO_CLASS_RT] = "realtime",
4833 [IOPRIO_CLASS_BE] = "best-effort",
4834 [IOPRIO_CLASS_IDLE] = "idle"
4837 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
4839 static const char *const sigchld_code_table[] = {
4840 [CLD_EXITED] = "exited",
4841 [CLD_KILLED] = "killed",
4842 [CLD_DUMPED] = "dumped",
4843 [CLD_TRAPPED] = "trapped",
4844 [CLD_STOPPED] = "stopped",
4845 [CLD_CONTINUED] = "continued",
4848 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
4850 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
4851 [LOG_FAC(LOG_KERN)] = "kern",
4852 [LOG_FAC(LOG_USER)] = "user",
4853 [LOG_FAC(LOG_MAIL)] = "mail",
4854 [LOG_FAC(LOG_DAEMON)] = "daemon",
4855 [LOG_FAC(LOG_AUTH)] = "auth",
4856 [LOG_FAC(LOG_SYSLOG)] = "syslog",
4857 [LOG_FAC(LOG_LPR)] = "lpr",
4858 [LOG_FAC(LOG_NEWS)] = "news",
4859 [LOG_FAC(LOG_UUCP)] = "uucp",
4860 [LOG_FAC(LOG_CRON)] = "cron",
4861 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
4862 [LOG_FAC(LOG_FTP)] = "ftp",
4863 [LOG_FAC(LOG_LOCAL0)] = "local0",
4864 [LOG_FAC(LOG_LOCAL1)] = "local1",
4865 [LOG_FAC(LOG_LOCAL2)] = "local2",
4866 [LOG_FAC(LOG_LOCAL3)] = "local3",
4867 [LOG_FAC(LOG_LOCAL4)] = "local4",
4868 [LOG_FAC(LOG_LOCAL5)] = "local5",
4869 [LOG_FAC(LOG_LOCAL6)] = "local6",
4870 [LOG_FAC(LOG_LOCAL7)] = "local7"
4873 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
4875 static const char *const log_level_table[] = {
4876 [LOG_EMERG] = "emerg",
4877 [LOG_ALERT] = "alert",
4878 [LOG_CRIT] = "crit",
4880 [LOG_WARNING] = "warning",
4881 [LOG_NOTICE] = "notice",
4882 [LOG_INFO] = "info",
4883 [LOG_DEBUG] = "debug"
4886 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
4888 static const char* const sched_policy_table[] = {
4889 [SCHED_OTHER] = "other",
4890 [SCHED_BATCH] = "batch",
4891 [SCHED_IDLE] = "idle",
4892 [SCHED_FIFO] = "fifo",
4896 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
4898 static const char* const rlimit_table[] = {
4899 [RLIMIT_CPU] = "LimitCPU",
4900 [RLIMIT_FSIZE] = "LimitFSIZE",
4901 [RLIMIT_DATA] = "LimitDATA",
4902 [RLIMIT_STACK] = "LimitSTACK",
4903 [RLIMIT_CORE] = "LimitCORE",
4904 [RLIMIT_RSS] = "LimitRSS",
4905 [RLIMIT_NOFILE] = "LimitNOFILE",
4906 [RLIMIT_AS] = "LimitAS",
4907 [RLIMIT_NPROC] = "LimitNPROC",
4908 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
4909 [RLIMIT_LOCKS] = "LimitLOCKS",
4910 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
4911 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
4912 [RLIMIT_NICE] = "LimitNICE",
4913 [RLIMIT_RTPRIO] = "LimitRTPRIO",
4914 [RLIMIT_RTTIME] = "LimitRTTIME"
4917 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
4919 static const char* const ip_tos_table[] = {
4920 [IPTOS_LOWDELAY] = "low-delay",
4921 [IPTOS_THROUGHPUT] = "throughput",
4922 [IPTOS_RELIABILITY] = "reliability",
4923 [IPTOS_LOWCOST] = "low-cost",
4926 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
4928 static const char *const __signal_table[] = {
4945 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
4956 [SIGVTALRM] = "VTALRM",
4958 [SIGWINCH] = "WINCH",
4964 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
4966 const char *signal_to_string(int signo) {
4967 static __thread char buf[12];
4970 name = __signal_to_string(signo);
4974 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
4975 snprintf(buf, sizeof(buf) - 1, "RTMIN+%d", signo - SIGRTMIN);
4977 snprintf(buf, sizeof(buf) - 1, "%d", signo);
4982 int signal_from_string(const char *s) {
4987 signo = __signal_from_string(s);
4991 if (startswith(s, "RTMIN+")) {
4995 if (safe_atou(s, &u) >= 0) {
4996 signo = (int) u + offset;
4997 if (signo > 0 && signo < _NSIG)
5003 bool kexec_loaded(void) {
5004 bool loaded = false;
5007 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
5015 int strdup_or_null(const char *a, char **b) {
5033 int prot_from_flags(int flags) {
5035 switch (flags & O_ACCMODE) {
5044 return PROT_READ|PROT_WRITE;
5051 char *format_bytes(char *buf, size_t l, off_t t) {
5054 static const struct {
5058 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5059 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5060 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
5061 { "G", 1024ULL*1024ULL*1024ULL },
5062 { "M", 1024ULL*1024ULL },
5066 for (i = 0; i < ELEMENTSOF(table); i++) {
5068 if (t >= table[i].factor) {
5071 (unsigned long long) (t / table[i].factor),
5072 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
5079 snprintf(buf, l, "%lluB", (unsigned long long) t);
5087 void* memdup(const void *p, size_t l) {
5100 int fd_inc_sndbuf(int fd, size_t n) {
5102 socklen_t l = sizeof(value);
5104 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
5106 l == sizeof(value) &&
5107 (size_t) value >= n*2)
5111 r = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value));
5118 int fd_inc_rcvbuf(int fd, size_t n) {
5120 socklen_t l = sizeof(value);
5122 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
5124 l == sizeof(value) &&
5125 (size_t) value >= n*2)
5129 r = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value));
5136 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
5137 pid_t parent_pid, agent_pid;
5139 bool stdout_is_tty, stderr_is_tty;
5147 parent_pid = getpid();
5149 /* Spawns a temporary TTY agent, making sure it goes away when
5156 if (agent_pid != 0) {
5163 * Make sure the agent goes away when the parent dies */
5164 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
5165 _exit(EXIT_FAILURE);
5167 /* Check whether our parent died before we were able
5168 * to set the death signal */
5169 if (getppid() != parent_pid)
5170 _exit(EXIT_SUCCESS);
5172 /* Don't leak fds to the agent */
5173 close_all_fds(except, n_except);
5175 stdout_is_tty = isatty(STDOUT_FILENO);
5176 stderr_is_tty = isatty(STDERR_FILENO);
5178 if (!stdout_is_tty || !stderr_is_tty) {
5179 /* Detach from stdout/stderr. and reopen
5180 * /dev/tty for them. This is important to
5181 * ensure that when systemctl is started via
5182 * popen() or a similar call that expects to
5183 * read EOF we actually do generate EOF and
5184 * not delay this indefinitely by because we
5185 * keep an unused copy of stdin around. */
5186 fd = open("/dev/tty", O_WRONLY);
5188 log_error("Failed to open /dev/tty: %m");
5189 _exit(EXIT_FAILURE);
5193 dup2(fd, STDOUT_FILENO);
5196 dup2(fd, STDERR_FILENO);
5202 /* Count arguments */
5204 for (n = 0; va_arg(ap, char*); n++)
5209 l = alloca(sizeof(char *) * (n + 1));
5211 /* Fill in arguments */
5213 for (i = 0; i <= n; i++)
5214 l[i] = va_arg(ap, char*);
5218 _exit(EXIT_FAILURE);
5221 int setrlimit_closest(int resource, const struct rlimit *rlim) {
5222 struct rlimit highest, fixed;
5226 if (setrlimit(resource, rlim) >= 0)
5232 /* So we failed to set the desired setrlimit, then let's try
5233 * to get as close as we can */
5234 assert_se(getrlimit(resource, &highest) == 0);
5236 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
5237 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
5239 if (setrlimit(resource, &fixed) < 0)
5245 int getenv_for_pid(pid_t pid, const char *field, char **_value) {
5246 char path[sizeof("/proc/")-1+10+sizeof("/environ")], *value = NULL;
5258 snprintf(path, sizeof(path), "/proc/%lu/environ", (unsigned long) pid);
5261 f = fopen(path, "re");
5269 char line[LINE_MAX];
5272 for (i = 0; i < sizeof(line)-1; i++) {
5276 if (_unlikely_(c == EOF)) {
5286 if (memcmp(line, field, l) == 0 && line[l] == '=') {
5287 value = strdup(line + l + 1);
5307 int can_sleep(const char *type) {
5311 _cleanup_free_ char *p = NULL;
5315 /* If /sys is read-only we cannot sleep */
5316 if (access("/sys/power/state", W_OK) < 0)
5319 r = read_one_line_file("/sys/power/state", &p);
5324 FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state)
5325 if (l == k && memcmp(w, type, l) == 0)
5331 int can_sleep_disk(const char *type) {
5335 _cleanup_free_ char *p = NULL;
5339 /* If /sys is read-only we cannot sleep */
5340 if (access("/sys/power/state", W_OK) < 0 ||
5341 access("/sys/power/disk", W_OK) < 0)
5344 r = read_one_line_file("/sys/power/disk", &p);
5349 FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state) {
5350 if (l == k && memcmp(w, type, l) == 0)
5353 if (l == k + 2 && w[0] == '[' && memcmp(w + 1, type, l - 2) == 0 && w[l-1] == ']')
5360 bool is_valid_documentation_url(const char *url) {
5363 if (startswith(url, "http://") && url[7])
5366 if (startswith(url, "https://") && url[8])
5369 if (startswith(url, "file:") && url[5])
5372 if (startswith(url, "info:") && url[5])
5375 if (startswith(url, "man:") && url[4])
5381 bool in_initrd(void) {
5382 static __thread int saved = -1;
5388 /* We make two checks here:
5390 * 1. the flag file /etc/initrd-release must exist
5391 * 2. the root file system must be a memory file system
5393 * The second check is extra paranoia, since misdetecting an
5394 * initrd can have bad bad consequences due the initrd
5395 * emptying when transititioning to the main systemd.
5398 saved = access("/etc/initrd-release", F_OK) >= 0 &&
5399 statfs("/", &s) >= 0 &&
5400 is_temporary_fs(&s);
5405 void warn_melody(void) {
5406 _cleanup_close_ int fd = -1;
5408 fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
5412 /* Yeah, this is synchronous. Kinda sucks. But well... */
5414 ioctl(fd, KIOCSOUND, (int)(1193180/440));
5415 usleep(125*USEC_PER_MSEC);
5417 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5418 usleep(125*USEC_PER_MSEC);
5420 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5421 usleep(125*USEC_PER_MSEC);
5423 ioctl(fd, KIOCSOUND, 0);
5426 int make_console_stdio(void) {
5429 /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
5431 fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1);
5433 log_error("Failed to acquire terminal: %s", strerror(-fd));
5439 log_error("Failed to duplicate terminal fd: %s", strerror(-r));
5446 int get_home_dir(char **_h) {
5454 /* Take the user specified one */
5465 /* Hardcode home directory for root to avoid NSS */
5468 h = strdup("/root");
5476 /* Check the database... */
5480 return errno ? -errno : -ESRCH;
5482 if (!path_is_absolute(p->pw_dir))
5485 h = strdup(p->pw_dir);
5493 int get_shell(char **_sh) {
5501 /* Take the user specified one */
5502 e = getenv("SHELL");
5512 /* Hardcode home directory for root to avoid NSS */
5515 sh = strdup("/bin/sh");
5523 /* Check the database... */
5527 return errno ? -errno : -ESRCH;
5529 if (!path_is_absolute(p->pw_shell))
5532 sh = strdup(p->pw_shell);
5540 void freep(void *p) {
5544 void fclosep(FILE **f) {
5549 void closep(int *fd) {
5551 close_nointr_nofail(*fd);
5554 void closedirp(DIR **d) {
5559 void umaskp(mode_t *u) {
5563 bool filename_is_safe(const char *p) {
5577 if (strlen(p) > FILENAME_MAX)
5583 bool string_is_safe(const char *p) {
5588 for (t = p; *t; t++) {
5589 if (*t > 0 && *t < ' ')
5592 if (strchr("\\\"\'", *t))
5599 /* hey glibc, APIs with callbacks without a user pointer are so useless */
5600 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
5601 int (*compar) (const void *, const void *, void *), void *arg) {
5610 p = (void *)(((const char *) base) + (idx * size));
5611 comparison = compar(key, p, arg);
5614 else if (comparison > 0)
5622 bool is_locale_utf8(void) {
5624 static int cached_answer = -1;
5626 if (cached_answer >= 0)
5629 if (!setlocale(LC_ALL, "")) {
5630 cached_answer = true;
5634 set = nl_langinfo(CODESET);
5636 cached_answer = true;
5640 cached_answer = streq(set, "UTF-8");
5642 return (bool)cached_answer;
5645 const char *draw_special_char(DrawSpecialChar ch) {
5646 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
5648 [DRAW_TREE_VERT] = "\342\224\202 ", /* │ */
5649 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
5650 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
5651 [DRAW_TRIANGULAR_BULLET] = "\342\200\243 ", /* ‣ */
5653 /* ASCII fallback */ {
5654 [DRAW_TREE_VERT] = "| ",
5655 [DRAW_TREE_BRANCH] = "|-",
5656 [DRAW_TREE_RIGHT] = "`-",
5657 [DRAW_TRIANGULAR_BULLET] = "> ",
5661 return draw_table[!is_locale_utf8()][ch];
5664 char *strreplace(const char *text, const char *old_string, const char *new_string) {
5667 size_t l, old_len, new_len;
5673 old_len = strlen(old_string);
5674 new_len = strlen(new_string);
5687 if (!startswith(f, old_string)) {
5693 nl = l - old_len + new_len;
5694 a = realloc(r, nl + 1);
5702 t = stpcpy(t, new_string);
5714 char *strip_tab_ansi(char **ibuf, size_t *_isz) {
5715 const char *i, *begin = NULL;
5720 } state = STATE_OTHER;
5722 size_t osz = 0, isz;
5728 /* Strips ANSI color and replaces TABs by 8 spaces */
5730 isz = _isz ? *_isz : strlen(*ibuf);
5732 f = open_memstream(&obuf, &osz);
5736 for (i = *ibuf; i < *ibuf + isz + 1; i++) {
5741 if (i >= *ibuf + isz) /* EOT */
5743 else if (*i == '\x1B')
5744 state = STATE_ESCAPE;
5745 else if (*i == '\t')
5752 if (i >= *ibuf + isz) { /* EOT */
5755 } else if (*i == '[') {
5756 state = STATE_BRACKET;
5761 state = STATE_OTHER;
5768 if (i >= *ibuf + isz || /* EOT */
5769 (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
5772 state = STATE_OTHER;
5774 } else if (*i == 'm')
5775 state = STATE_OTHER;
5797 int on_ac_power(void) {
5798 bool found_offline = false, found_online = false;
5799 _cleanup_closedir_ DIR *d = NULL;
5801 d = opendir("/sys/class/power_supply");
5807 union dirent_storage buf;
5808 _cleanup_free_ char *p = NULL;
5809 _cleanup_close_ int fd = -1, device = -1;
5814 k = readdir_r(d, &buf.de, &de);
5821 if (ignore_file(de->d_name))
5824 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
5826 if (errno == ENOENT || errno == ENOTDIR)
5832 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
5834 if (errno == ENOENT)
5840 n = read(fd, contents, sizeof(contents));
5844 if (n != 6 || memcmp(contents, "Mains\n", 6))
5847 close_nointr_nofail(fd);
5848 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
5850 if (errno == ENOENT)
5856 n = read(fd, contents, sizeof(contents));
5860 if (n != 2 || contents[1] != '\n')
5863 if (contents[0] == '1') {
5864 found_online = true;
5866 } else if (contents[0] == '0')
5867 found_offline = true;
5872 return found_online || !found_offline;