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;
446 /* Let's skip the pid and comm fields. The latter is enclosed
447 * in () but does not escape any () in its value, so let's
448 * skip over it manually */
450 p = strrchr(line, ')');
462 if ((long unsigned) (pid_t) ppid != ppid)
465 *_ppid = (pid_t) ppid;
470 int get_starttime_of_pid(pid_t pid, unsigned long long *st) {
471 _cleanup_fclose_ FILE *f = NULL;
472 char fn[PATH_MAX], line[LINE_MAX], *p;
477 assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1));
484 if (!fgets(line, sizeof(line), f)) {
491 /* Let's skip the pid and comm fields. The latter is enclosed
492 * in () but does not escape any () in its value, so let's
493 * skip over it manually */
495 p = strrchr(line, ')');
517 "%*d " /* priority */
519 "%*d " /* num_threads */
520 "%*d " /* itrealvalue */
521 "%llu " /* starttime */,
528 int write_one_line_file(const char *fn, const char *line) {
529 _cleanup_fclose_ FILE *f = NULL;
539 if (fputs(line, f) < 0)
540 return errno ? -errno : -EIO;
542 if (!endswith(line, "\n"))
548 return errno ? -errno : -EIO;
553 int fchmod_umask(int fd, mode_t m) {
558 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
564 int write_one_line_file_atomic(const char *fn, const char *line) {
572 r = fopen_temporary(fn, &f, &p);
576 fchmod_umask(fileno(f), 0644);
579 if (fputs(line, f) < 0) {
584 if (!endswith(line, "\n"))
595 if (rename(p, fn) < 0)
611 int read_one_line_file(const char *fn, char **line) {
612 _cleanup_fclose_ FILE *f = NULL;
613 char t[LINE_MAX], *c;
622 if (!fgets(t, sizeof(t), f)) {
625 return errno ? -errno : -EIO;
639 int read_full_file(const char *fn, char **contents, size_t *size) {
640 _cleanup_fclose_ FILE *f = NULL;
642 _cleanup_free_ char *buf = NULL;
649 if (fstat(fileno(f), &st) < 0)
653 if (st.st_size > 4*1024*1024)
656 n = st.st_size > 0 ? st.st_size : LINE_MAX;
663 t = realloc(buf, n+1);
668 k = fread(buf + l, 1, n - l, f);
697 const char *separator, ...) {
700 char *contents = NULL, *p;
705 if ((r = read_full_file(fname, &contents, NULL)) < 0)
710 const char *key = NULL;
712 p += strspn(p, separator);
713 p += strspn(p, WHITESPACE);
718 if (!strchr(COMMENTS, *p)) {
722 va_start(ap, separator);
723 while ((key = va_arg(ap, char *))) {
727 value = va_arg(ap, char **);
730 if (strncmp(p, key, n) != 0 ||
735 n = strcspn(p, separator);
738 strchr(QUOTES, p[0]) &&
740 v = strndup(p+1, n-2);
751 /* return empty value strings as NULL */
768 p += strcspn(p, separator);
787 if (!(f = fopen(fname, "re")))
791 char l[LINE_MAX], *p, *u;
794 if (!fgets(l, sizeof(l), f)) {
807 if (strchr(COMMENTS, *p))
810 if (!(u = normalize_env_assignment(p))) {
815 t = strv_append(m, u);
841 int write_env_file(const char *fname, char **l) {
846 r = fopen_temporary(fname, &f, &p);
850 fchmod_umask(fileno(f), 0644);
866 if (rename(p, fname) < 0)
881 char *truncate_nl(char *s) {
884 s[strcspn(s, NEWLINE)] = 0;
888 int get_process_comm(pid_t pid, char **name) {
894 r = read_one_line_file("/proc/self/comm", name);
897 if (asprintf(&p, "/proc/%lu/comm", (unsigned long) pid) < 0)
900 r = read_one_line_file(p, name);
907 int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
914 assert(max_length > 0);
918 f = fopen("/proc/self/cmdline", "re");
921 if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
931 r = new(char, max_length);
939 while ((c = getc(f)) != EOF) {
961 size_t n = MIN(left-1, 3U);
969 /* Kernel threads have no argv[] */
979 h = get_process_comm(pid, &t);
983 r = strjoin("[", t, "]", NULL);
994 int is_kernel_thread(pid_t pid) {
1004 if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
1013 count = fread(&c, 1, 1, f);
1017 /* Kernel threads have an empty cmdline */
1020 return eof ? 1 : -errno;
1025 int get_process_exe(pid_t pid, char **name) {
1031 r = readlink_malloc("/proc/self/exe", name);
1034 if (asprintf(&p, "/proc/%lu/exe", (unsigned long) pid) < 0)
1037 r = readlink_malloc(p, name);
1044 static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
1054 if (asprintf(&p, "/proc/%lu/status", (unsigned long) pid) < 0)
1064 char line[LINE_MAX], *l;
1066 if (!fgets(line, sizeof(line), f)) {
1076 if (startswith(l, field)) {
1078 l += strspn(l, WHITESPACE);
1080 l[strcspn(l, WHITESPACE)] = 0;
1082 r = parse_uid(l, uid);
1095 int get_process_uid(pid_t pid, uid_t *uid) {
1096 return get_process_id(pid, "Uid:", uid);
1099 int get_process_gid(pid_t pid, gid_t *gid) {
1100 return get_process_id(pid, "Gid:", gid);
1103 char *strnappend(const char *s, const char *suffix, size_t b) {
1111 return strndup(suffix, b);
1120 if (b > ((size_t) -1) - a)
1123 r = new(char, a+b+1);
1128 memcpy(r+a, suffix, b);
1134 char *strappend(const char *s, const char *suffix) {
1135 return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
1138 int readlink_malloc(const char *p, char **r) {
1148 if (!(c = new(char, l)))
1151 if ((n = readlink(p, c, l-1)) < 0) {
1157 if ((size_t) n < l-1) {
1168 int readlink_and_make_absolute(const char *p, char **r) {
1175 if ((j = readlink_malloc(p, &target)) < 0)
1178 k = file_in_same_dir(p, target);
1188 int readlink_and_canonicalize(const char *p, char **r) {
1195 j = readlink_and_make_absolute(p, &t);
1199 s = canonicalize_file_name(t);
1206 path_kill_slashes(*r);
1211 int reset_all_signal_handlers(void) {
1214 for (sig = 1; sig < _NSIG; sig++) {
1215 struct sigaction sa;
1217 if (sig == SIGKILL || sig == SIGSTOP)
1221 sa.sa_handler = SIG_DFL;
1222 sa.sa_flags = SA_RESTART;
1224 /* On Linux the first two RT signals are reserved by
1225 * glibc, and sigaction() will return EINVAL for them. */
1226 if ((sigaction(sig, &sa, NULL) < 0))
1227 if (errno != EINVAL)
1234 char *strstrip(char *s) {
1237 /* Drops trailing whitespace. Modifies the string in
1238 * place. Returns pointer to first non-space character */
1240 s += strspn(s, WHITESPACE);
1242 for (e = strchr(s, 0); e > s; e --)
1243 if (!strchr(WHITESPACE, e[-1]))
1251 char *delete_chars(char *s, const char *bad) {
1254 /* Drops all whitespace, regardless where in the string */
1256 for (f = s, t = s; *f; f++) {
1257 if (strchr(bad, *f))
1268 bool in_charset(const char *s, const char* charset) {
1274 for (i = s; *i; i++)
1275 if (!strchr(charset, *i))
1281 char *file_in_same_dir(const char *path, const char *filename) {
1288 /* This removes the last component of path and appends
1289 * filename, unless the latter is absolute anyway or the
1292 if (path_is_absolute(filename))
1293 return strdup(filename);
1295 if (!(e = strrchr(path, '/')))
1296 return strdup(filename);
1298 k = strlen(filename);
1299 if (!(r = new(char, e-path+1+k+1)))
1302 memcpy(r, path, e-path+1);
1303 memcpy(r+(e-path)+1, filename, k+1);
1308 int rmdir_parents(const char *path, const char *stop) {
1317 /* Skip trailing slashes */
1318 while (l > 0 && path[l-1] == '/')
1324 /* Skip last component */
1325 while (l > 0 && path[l-1] != '/')
1328 /* Skip trailing slashes */
1329 while (l > 0 && path[l-1] == '/')
1335 if (!(t = strndup(path, l)))
1338 if (path_startswith(stop, t)) {
1347 if (errno != ENOENT)
1355 char hexchar(int x) {
1356 static const char table[16] = "0123456789abcdef";
1358 return table[x & 15];
1361 int unhexchar(char c) {
1363 if (c >= '0' && c <= '9')
1366 if (c >= 'a' && c <= 'f')
1367 return c - 'a' + 10;
1369 if (c >= 'A' && c <= 'F')
1370 return c - 'A' + 10;
1375 char octchar(int x) {
1376 return '0' + (x & 7);
1379 int unoctchar(char c) {
1381 if (c >= '0' && c <= '7')
1387 char decchar(int x) {
1388 return '0' + (x % 10);
1391 int undecchar(char c) {
1393 if (c >= '0' && c <= '9')
1399 char *cescape(const char *s) {
1405 /* Does C style string escaping. */
1407 r = new(char, strlen(s)*4 + 1);
1411 for (f = s, t = r; *f; f++)
1457 /* For special chars we prefer octal over
1458 * hexadecimal encoding, simply because glib's
1459 * g_strescape() does the same */
1460 if ((*f < ' ') || (*f >= 127)) {
1462 *(t++) = octchar((unsigned char) *f >> 6);
1463 *(t++) = octchar((unsigned char) *f >> 3);
1464 *(t++) = octchar((unsigned char) *f);
1475 char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix) {
1482 /* Undoes C style string escaping, and optionally prefixes it. */
1484 pl = prefix ? strlen(prefix) : 0;
1486 r = new(char, pl+length+1);
1491 memcpy(r, prefix, pl);
1493 for (f = s, t = r + pl; f < s + length; f++) {
1536 /* This is an extension of the XDG syntax files */
1541 /* hexadecimal encoding */
1544 a = unhexchar(f[1]);
1545 b = unhexchar(f[2]);
1547 if (a < 0 || b < 0) {
1548 /* Invalid escape code, let's take it literal then */
1552 *(t++) = (char) ((a << 4) | b);
1567 /* octal encoding */
1570 a = unoctchar(f[0]);
1571 b = unoctchar(f[1]);
1572 c = unoctchar(f[2]);
1574 if (a < 0 || b < 0 || c < 0) {
1575 /* Invalid escape code, let's take it literal then */
1579 *(t++) = (char) ((a << 6) | (b << 3) | c);
1587 /* premature end of string.*/
1592 /* Invalid escape code, let's take it literal then */
1604 char *cunescape_length(const char *s, size_t length) {
1605 return cunescape_length_with_prefix(s, length, NULL);
1608 char *cunescape(const char *s) {
1611 return cunescape_length(s, strlen(s));
1614 char *xescape(const char *s, const char *bad) {
1618 /* Escapes all chars in bad, in addition to \ and all special
1619 * chars, in \xFF style escaping. May be reversed with
1622 r = new(char, strlen(s) * 4 + 1);
1626 for (f = s, t = r; *f; f++) {
1628 if ((*f < ' ') || (*f >= 127) ||
1629 (*f == '\\') || strchr(bad, *f)) {
1632 *(t++) = hexchar(*f >> 4);
1633 *(t++) = hexchar(*f);
1643 char *bus_path_escape(const char *s) {
1649 /* Escapes all chars that D-Bus' object path cannot deal
1650 * with. Can be reverse with bus_path_unescape() */
1652 if (!(r = new(char, strlen(s)*3+1)))
1655 for (f = s, t = r; *f; f++) {
1657 if (!(*f >= 'A' && *f <= 'Z') &&
1658 !(*f >= 'a' && *f <= 'z') &&
1659 !(*f >= '0' && *f <= '9')) {
1661 *(t++) = hexchar(*f >> 4);
1662 *(t++) = hexchar(*f);
1672 char *bus_path_unescape(const char *f) {
1677 if (!(r = strdup(f)))
1680 for (t = r; *f; f++) {
1685 if ((a = unhexchar(f[1])) < 0 ||
1686 (b = unhexchar(f[2])) < 0) {
1687 /* Invalid escape code, let's take it literal then */
1690 *(t++) = (char) ((a << 4) | b);
1702 char *ascii_strlower(char *t) {
1707 for (p = t; *p; p++)
1708 if (*p >= 'A' && *p <= 'Z')
1709 *p = *p - 'A' + 'a';
1714 static bool ignore_file_allow_backup(const char *filename) {
1718 filename[0] == '.' ||
1719 streq(filename, "lost+found") ||
1720 streq(filename, "aquota.user") ||
1721 streq(filename, "aquota.group") ||
1722 endswith(filename, ".rpmnew") ||
1723 endswith(filename, ".rpmsave") ||
1724 endswith(filename, ".rpmorig") ||
1725 endswith(filename, ".dpkg-old") ||
1726 endswith(filename, ".dpkg-new") ||
1727 endswith(filename, ".swp");
1730 bool ignore_file(const char *filename) {
1733 if (endswith(filename, "~"))
1736 return ignore_file_allow_backup(filename);
1739 int fd_nonblock(int fd, bool nonblock) {
1744 if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
1748 flags |= O_NONBLOCK;
1750 flags &= ~O_NONBLOCK;
1752 if (fcntl(fd, F_SETFL, flags) < 0)
1758 int fd_cloexec(int fd, bool cloexec) {
1763 if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
1767 flags |= FD_CLOEXEC;
1769 flags &= ~FD_CLOEXEC;
1771 if (fcntl(fd, F_SETFD, flags) < 0)
1777 static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
1780 assert(n_fdset == 0 || fdset);
1782 for (i = 0; i < n_fdset; i++)
1789 int close_all_fds(const int except[], unsigned n_except) {
1794 assert(n_except == 0 || except);
1796 d = opendir("/proc/self/fd");
1801 /* When /proc isn't available (for example in chroots)
1802 * the fallback is brute forcing through the fd
1805 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
1806 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
1808 if (fd_in_set(fd, except, n_except))
1811 if (close_nointr(fd) < 0)
1812 if (errno != EBADF && r == 0)
1819 while ((de = readdir(d))) {
1822 if (ignore_file(de->d_name))
1825 if (safe_atoi(de->d_name, &fd) < 0)
1826 /* Let's better ignore this, just in case */
1835 if (fd_in_set(fd, except, n_except))
1838 if (close_nointr(fd) < 0) {
1839 /* Valgrind has its own FD and doesn't want to have it closed */
1840 if (errno != EBADF && r == 0)
1849 bool chars_intersect(const char *a, const char *b) {
1852 /* Returns true if any of the chars in a are in b. */
1853 for (p = a; *p; p++)
1860 bool fstype_is_network(const char *fstype) {
1861 static const char table[] =
1870 return nulstr_contains(table, fstype);
1874 _cleanup_close_ int fd;
1876 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
1882 TIOCL_GETKMSGREDIRECT,
1886 if (ioctl(fd, TIOCLINUX, tiocl) < 0)
1889 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
1892 if (ioctl(fd, VT_ACTIVATE, vt) < 0)
1898 int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
1899 struct termios old_termios, new_termios;
1901 char line[LINE_MAX];
1906 if (tcgetattr(fileno(f), &old_termios) >= 0) {
1907 new_termios = old_termios;
1909 new_termios.c_lflag &= ~ICANON;
1910 new_termios.c_cc[VMIN] = 1;
1911 new_termios.c_cc[VTIME] = 0;
1913 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
1916 if (t != (usec_t) -1) {
1917 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
1918 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
1923 k = fread(&c, 1, 1, f);
1925 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
1931 *need_nl = c != '\n';
1938 if (t != (usec_t) -1)
1939 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
1942 if (!fgets(line, sizeof(line), f))
1947 if (strlen(line) != 1)
1957 int ask(char *ret, const char *replies, const char *text, ...) {
1967 bool need_nl = true;
1970 fputs(ANSI_HIGHLIGHT_ON, stdout);
1977 fputs(ANSI_HIGHLIGHT_OFF, stdout);
1981 r = read_one_char(stdin, &c, (usec_t) -1, &need_nl);
1984 if (r == -EBADMSG) {
1985 puts("Bad input, please try again.");
1996 if (strchr(replies, c)) {
2001 puts("Read unexpected character, please try again.");
2005 int reset_terminal_fd(int fd, bool switch_to_text) {
2006 struct termios termios;
2009 /* Set terminal to some sane defaults */
2013 /* We leave locked terminal attributes untouched, so that
2014 * Plymouth may set whatever it wants to set, and we don't
2015 * interfere with that. */
2017 /* Disable exclusive mode, just in case */
2018 ioctl(fd, TIOCNXCL);
2020 /* Switch to text mode */
2022 ioctl(fd, KDSETMODE, KD_TEXT);
2024 /* Enable console unicode mode */
2025 ioctl(fd, KDSKBMODE, K_UNICODE);
2027 if (tcgetattr(fd, &termios) < 0) {
2032 /* We only reset the stuff that matters to the software. How
2033 * hardware is set up we don't touch assuming that somebody
2034 * else will do that for us */
2036 termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
2037 termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
2038 termios.c_oflag |= ONLCR;
2039 termios.c_cflag |= CREAD;
2040 termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
2042 termios.c_cc[VINTR] = 03; /* ^C */
2043 termios.c_cc[VQUIT] = 034; /* ^\ */
2044 termios.c_cc[VERASE] = 0177;
2045 termios.c_cc[VKILL] = 025; /* ^X */
2046 termios.c_cc[VEOF] = 04; /* ^D */
2047 termios.c_cc[VSTART] = 021; /* ^Q */
2048 termios.c_cc[VSTOP] = 023; /* ^S */
2049 termios.c_cc[VSUSP] = 032; /* ^Z */
2050 termios.c_cc[VLNEXT] = 026; /* ^V */
2051 termios.c_cc[VWERASE] = 027; /* ^W */
2052 termios.c_cc[VREPRINT] = 022; /* ^R */
2053 termios.c_cc[VEOL] = 0;
2054 termios.c_cc[VEOL2] = 0;
2056 termios.c_cc[VTIME] = 0;
2057 termios.c_cc[VMIN] = 1;
2059 if (tcsetattr(fd, TCSANOW, &termios) < 0)
2063 /* Just in case, flush all crap out */
2064 tcflush(fd, TCIOFLUSH);
2069 int reset_terminal(const char *name) {
2072 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2076 r = reset_terminal_fd(fd, true);
2077 close_nointr_nofail(fd);
2082 int open_terminal(const char *name, int mode) {
2087 * If a TTY is in the process of being closed opening it might
2088 * cause EIO. This is horribly awful, but unlikely to be
2089 * changed in the kernel. Hence we work around this problem by
2090 * retrying a couple of times.
2092 * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
2096 fd = open(name, mode);
2103 /* Max 1s in total */
2107 usleep(50 * USEC_PER_MSEC);
2116 close_nointr_nofail(fd);
2121 close_nointr_nofail(fd);
2128 int flush_fd(int fd) {
2129 struct pollfd pollfd;
2133 pollfd.events = POLLIN;
2140 if ((r = poll(&pollfd, 1, 0)) < 0) {
2151 if ((l = read(fd, buf, sizeof(buf))) < 0) {
2156 if (errno == EAGAIN)
2167 int acquire_terminal(
2171 bool ignore_tiocstty_eperm,
2174 int fd = -1, notify = -1, r = 0, wd = -1;
2176 struct sigaction sa_old, sa_new;
2180 /* We use inotify to be notified when the tty is closed. We
2181 * create the watch before checking if we can actually acquire
2182 * it, so that we don't lose any event.
2184 * Note: strictly speaking this actually watches for the
2185 * device being closed, it does *not* really watch whether a
2186 * tty loses its controlling process. However, unless some
2187 * rogue process uses TIOCNOTTY on /dev/tty *after* closing
2188 * its tty otherwise this will not become a problem. As long
2189 * as the administrator makes sure not configure any service
2190 * on the same tty as an untrusted user this should not be a
2191 * problem. (Which he probably should not do anyway.) */
2193 if (timeout != (usec_t) -1)
2194 ts = now(CLOCK_MONOTONIC);
2196 if (!fail && !force) {
2197 notify = inotify_init1(IN_CLOEXEC | (timeout != (usec_t) -1 ? IN_NONBLOCK : 0));
2203 wd = inotify_add_watch(notify, name, IN_CLOSE);
2212 r = flush_fd(notify);
2217 /* We pass here O_NOCTTY only so that we can check the return
2218 * value TIOCSCTTY and have a reliable way to figure out if we
2219 * successfully became the controlling process of the tty */
2220 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2224 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2225 * if we already own the tty. */
2227 sa_new.sa_handler = SIG_IGN;
2228 sa_new.sa_flags = SA_RESTART;
2229 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2231 /* First, try to get the tty */
2232 if (ioctl(fd, TIOCSCTTY, force) < 0)
2235 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2237 /* Sometimes it makes sense to ignore TIOCSCTTY
2238 * returning EPERM, i.e. when very likely we already
2239 * are have this controlling terminal. */
2240 if (r < 0 && r == -EPERM && ignore_tiocstty_eperm)
2243 if (r < 0 && (force || fail || r != -EPERM)) {
2252 assert(notify >= 0);
2255 uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
2257 struct inotify_event *e;
2259 if (timeout != (usec_t) -1) {
2262 n = now(CLOCK_MONOTONIC);
2263 if (ts + timeout < n) {
2268 r = fd_wait_for_event(fd, POLLIN, ts + timeout - n);
2278 l = read(notify, inotify_buffer, sizeof(inotify_buffer));
2281 if (errno == EINTR || errno == EAGAIN)
2288 e = (struct inotify_event*) inotify_buffer;
2293 if (e->wd != wd || !(e->mask & IN_CLOSE)) {
2298 step = sizeof(struct inotify_event) + e->len;
2299 assert(step <= (size_t) l);
2301 e = (struct inotify_event*) ((uint8_t*) e + step);
2308 /* We close the tty fd here since if the old session
2309 * ended our handle will be dead. It's important that
2310 * we do this after sleeping, so that we don't enter
2311 * an endless loop. */
2312 close_nointr_nofail(fd);
2316 close_nointr_nofail(notify);
2318 r = reset_terminal_fd(fd, true);
2320 log_warning("Failed to reset terminal: %s", strerror(-r));
2326 close_nointr_nofail(fd);
2329 close_nointr_nofail(notify);
2334 int release_terminal(void) {
2336 struct sigaction sa_old, sa_new;
2338 if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC)) < 0)
2341 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2342 * by our own TIOCNOTTY */
2345 sa_new.sa_handler = SIG_IGN;
2346 sa_new.sa_flags = SA_RESTART;
2347 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2349 if (ioctl(fd, TIOCNOTTY) < 0)
2352 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2354 close_nointr_nofail(fd);
2358 int sigaction_many(const struct sigaction *sa, ...) {
2363 while ((sig = va_arg(ap, int)) > 0)
2364 if (sigaction(sig, sa, NULL) < 0)
2371 int ignore_signals(int sig, ...) {
2372 struct sigaction sa;
2377 sa.sa_handler = SIG_IGN;
2378 sa.sa_flags = SA_RESTART;
2380 if (sigaction(sig, &sa, NULL) < 0)
2384 while ((sig = va_arg(ap, int)) > 0)
2385 if (sigaction(sig, &sa, NULL) < 0)
2392 int default_signals(int sig, ...) {
2393 struct sigaction sa;
2398 sa.sa_handler = SIG_DFL;
2399 sa.sa_flags = SA_RESTART;
2401 if (sigaction(sig, &sa, NULL) < 0)
2405 while ((sig = va_arg(ap, int)) > 0)
2406 if (sigaction(sig, &sa, NULL) < 0)
2413 int close_pipe(int p[]) {
2419 a = close_nointr(p[0]);
2424 b = close_nointr(p[1]);
2428 return a < 0 ? a : b;
2431 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2440 while (nbytes > 0) {
2443 if ((k = read(fd, p, nbytes)) <= 0) {
2445 if (k < 0 && errno == EINTR)
2448 if (k < 0 && errno == EAGAIN && do_poll) {
2449 struct pollfd pollfd;
2453 pollfd.events = POLLIN;
2455 if (poll(&pollfd, 1, -1) < 0) {
2459 return n > 0 ? n : -errno;
2462 if (pollfd.revents != POLLIN)
2463 return n > 0 ? n : -EIO;
2468 return n > 0 ? n : (k < 0 ? -errno : 0);
2479 ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2488 while (nbytes > 0) {
2491 k = write(fd, p, nbytes);
2494 if (k < 0 && errno == EINTR)
2497 if (k < 0 && errno == EAGAIN && do_poll) {
2498 struct pollfd pollfd;
2502 pollfd.events = POLLOUT;
2504 if (poll(&pollfd, 1, -1) < 0) {
2508 return n > 0 ? n : -errno;
2511 if (pollfd.revents != POLLOUT)
2512 return n > 0 ? n : -EIO;
2517 return n > 0 ? n : (k < 0 ? -errno : 0);
2528 int parse_bytes(const char *t, off_t *bytes) {
2529 static const struct {
2535 { "M", 1024ULL*1024ULL },
2536 { "G", 1024ULL*1024ULL*1024ULL },
2537 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2538 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2539 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2556 l = strtoll(p, &e, 10);
2567 e += strspn(e, WHITESPACE);
2569 for (i = 0; i < ELEMENTSOF(table); i++)
2570 if (startswith(e, table[i].suffix)) {
2571 r += (off_t) l * table[i].factor;
2572 p = e + strlen(table[i].suffix);
2576 if (i >= ELEMENTSOF(table))
2586 int make_stdio(int fd) {
2591 r = dup3(fd, STDIN_FILENO, 0);
2592 s = dup3(fd, STDOUT_FILENO, 0);
2593 t = dup3(fd, STDERR_FILENO, 0);
2596 close_nointr_nofail(fd);
2598 if (r < 0 || s < 0 || t < 0)
2601 /* We rely here that the new fd has O_CLOEXEC not set */
2606 int make_null_stdio(void) {
2609 null_fd = open("/dev/null", O_RDWR|O_NOCTTY);
2613 return make_stdio(null_fd);
2616 bool is_device_path(const char *path) {
2618 /* Returns true on paths that refer to a device, either in
2619 * sysfs or in /dev */
2622 path_startswith(path, "/dev/") ||
2623 path_startswith(path, "/sys/");
2626 int dir_is_empty(const char *path) {
2627 _cleanup_closedir_ DIR *d;
2636 union dirent_storage buf;
2638 r = readdir_r(d, &buf.de, &de);
2645 if (!ignore_file(de->d_name))
2650 unsigned long long random_ull(void) {
2651 _cleanup_close_ int fd;
2655 fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
2659 r = loop_read(fd, &ull, sizeof(ull), true);
2660 if (r != sizeof(ull))
2666 return random() * RAND_MAX + random();
2669 void rename_process(const char name[8]) {
2672 /* This is a like a poor man's setproctitle(). It changes the
2673 * comm field, argv[0], and also the glibc's internally used
2674 * name of the process. For the first one a limit of 16 chars
2675 * applies, to the second one usually one of 10 (i.e. length
2676 * of "/sbin/init"), to the third one one of 7 (i.e. length of
2677 * "systemd"). If you pass a longer string it will be
2680 prctl(PR_SET_NAME, name);
2682 if (program_invocation_name)
2683 strncpy(program_invocation_name, name, strlen(program_invocation_name));
2685 if (saved_argc > 0) {
2689 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
2691 for (i = 1; i < saved_argc; i++) {
2695 memset(saved_argv[i], 0, strlen(saved_argv[i]));
2700 void sigset_add_many(sigset_t *ss, ...) {
2707 while ((sig = va_arg(ap, int)) > 0)
2708 assert_se(sigaddset(ss, sig) == 0);
2712 char* gethostname_malloc(void) {
2715 assert_se(uname(&u) >= 0);
2717 if (!isempty(u.nodename) && !streq(u.nodename, "(none)"))
2718 return strdup(u.nodename);
2720 return strdup(u.sysname);
2723 bool hostname_is_set(void) {
2726 assert_se(uname(&u) >= 0);
2728 return !isempty(u.nodename) && !streq(u.nodename, "(none)");
2731 static char *lookup_uid(uid_t uid) {
2734 _cleanup_free_ char *buf = NULL;
2735 struct passwd pwbuf, *pw = NULL;
2737 /* Shortcut things to avoid NSS lookups */
2739 return strdup("root");
2741 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
2745 buf = malloc(bufsize);
2749 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
2750 return strdup(pw->pw_name);
2752 if (asprintf(&name, "%lu", (unsigned long) uid) < 0)
2758 char* getlogname_malloc(void) {
2762 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
2767 return lookup_uid(uid);
2770 char *getusername_malloc(void) {
2777 return lookup_uid(getuid());
2780 int getttyname_malloc(int fd, char **r) {
2781 char path[PATH_MAX], *c;
2786 k = ttyname_r(fd, path, sizeof(path));
2792 c = strdup(startswith(path, "/dev/") ? path + 5 : path);
2800 int getttyname_harder(int fd, char **r) {
2804 k = getttyname_malloc(fd, &s);
2808 if (streq(s, "tty")) {
2810 return get_ctty(0, NULL, r);
2817 int get_ctty_devnr(pid_t pid, dev_t *d) {
2819 char line[LINE_MAX], *p, *fn;
2820 unsigned long ttynr;
2823 if (asprintf(&fn, "/proc/%lu/stat", (unsigned long) (pid <= 0 ? getpid() : pid)) < 0)
2826 f = fopen(fn, "re");
2831 if (!fgets(line, sizeof(line), f)) {
2832 k = feof(f) ? -EIO : -errno;
2839 p = strrchr(line, ')');
2849 "%*d " /* session */
2854 if (major(ttynr) == 0 && minor(ttynr) == 0)
2861 int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
2863 char fn[PATH_MAX], *s, *b, *p;
2868 k = get_ctty_devnr(pid, &devnr);
2872 snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
2875 k = readlink_malloc(fn, &s);
2881 /* This is an ugly hack */
2882 if (major(devnr) == 136) {
2883 if (asprintf(&b, "pts/%lu", (unsigned long) minor(devnr)) < 0)
2893 /* Probably something like the ptys which have no
2894 * symlink in /dev/char. Let's return something
2895 * vaguely useful. */
2908 if (startswith(s, "/dev/"))
2910 else if (startswith(s, "../"))
2928 int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
2934 /* This returns the first error we run into, but nevertheless
2935 * tries to go on. This closes the passed fd. */
2939 close_nointr_nofail(fd);
2941 return errno == ENOENT ? 0 : -errno;
2946 union dirent_storage buf;
2947 bool is_dir, keep_around;
2951 r = readdir_r(d, &buf.de, &de);
2952 if (r != 0 && ret == 0) {
2960 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
2963 if (de->d_type == DT_UNKNOWN ||
2965 (de->d_type == DT_DIR && root_dev)) {
2966 if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
2967 if (ret == 0 && errno != ENOENT)
2972 is_dir = S_ISDIR(st.st_mode);
2975 (st.st_uid == 0 || st.st_uid == getuid()) &&
2976 (st.st_mode & S_ISVTX);
2978 is_dir = de->d_type == DT_DIR;
2979 keep_around = false;
2985 /* if root_dev is set, remove subdirectories only, if device is same as dir */
2986 if (root_dev && st.st_dev != root_dev->st_dev)
2989 subdir_fd = openat(fd, de->d_name,
2990 O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
2991 if (subdir_fd < 0) {
2992 if (ret == 0 && errno != ENOENT)
2997 r = rm_rf_children_dangerous(subdir_fd, only_dirs, honour_sticky, root_dev);
2998 if (r < 0 && ret == 0)
3002 if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
3003 if (ret == 0 && errno != ENOENT)
3007 } else if (!only_dirs && !keep_around) {
3009 if (unlinkat(fd, de->d_name, 0) < 0) {
3010 if (ret == 0 && errno != ENOENT)
3021 static int is_temporary_fs(struct statfs *s) {
3023 return s->f_type == TMPFS_MAGIC ||
3024 (long)s->f_type == (long)RAMFS_MAGIC;
3027 int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
3032 if (fstatfs(fd, &s) < 0) {
3033 close_nointr_nofail(fd);
3037 /* We refuse to clean disk file systems with this call. This
3038 * is extra paranoia just to be sure we never ever remove
3040 if (!is_temporary_fs(&s)) {
3041 log_error("Attempted to remove disk file system, and we can't allow that.");
3042 close_nointr_nofail(fd);
3046 return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev);
3049 static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
3055 /* We refuse to clean the root file system with this
3056 * call. This is extra paranoia to never cause a really
3057 * seriously broken system. */
3058 if (path_equal(path, "/")) {
3059 log_error("Attempted to remove entire root file system, and we can't allow that.");
3063 fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3066 if (errno != ENOTDIR)
3070 if (statfs(path, &s) < 0)
3073 if (!is_temporary_fs(&s)) {
3074 log_error("Attempted to remove disk file system, and we can't allow that.");
3079 if (delete_root && !only_dirs)
3080 if (unlink(path) < 0 && errno != ENOENT)
3087 if (fstatfs(fd, &s) < 0) {
3088 close_nointr_nofail(fd);
3092 if (!is_temporary_fs(&s)) {
3093 log_error("Attempted to remove disk file system, and we can't allow that.");
3094 close_nointr_nofail(fd);
3099 r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL);
3102 if (honour_sticky && file_is_priv_sticky(path) > 0)
3105 if (rmdir(path) < 0 && errno != ENOENT) {
3114 int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3115 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false);
3118 int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3119 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, true);
3122 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
3125 /* Under the assumption that we are running privileged we
3126 * first change the access mode and only then hand out
3127 * ownership to avoid a window where access is too open. */
3129 if (mode != (mode_t) -1)
3130 if (chmod(path, mode) < 0)
3133 if (uid != (uid_t) -1 || gid != (gid_t) -1)
3134 if (chown(path, uid, gid) < 0)
3140 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
3143 /* Under the assumption that we are running privileged we
3144 * first change the access mode and only then hand out
3145 * ownership to avoid a window where access is too open. */
3147 if (fchmod(fd, mode) < 0)
3150 if (fchown(fd, uid, gid) < 0)
3156 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
3160 /* Allocates the cpuset in the right size */
3163 if (!(r = CPU_ALLOC(n)))
3166 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
3167 CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
3177 if (errno != EINVAL)
3184 int status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) {
3185 static const char status_indent[] = " "; /* "[" STATUS "] " */
3186 _cleanup_free_ char *s = NULL;
3187 _cleanup_close_ int fd = -1;
3188 struct iovec iovec[5];
3193 /* This is independent of logging, as status messages are
3194 * optional and go exclusively to the console. */
3196 if (vasprintf(&s, format, ap) < 0)
3199 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
3212 sl = status ? sizeof(status_indent)-1 : 0;
3218 e = ellipsize(s, emax, 75);
3228 if (!isempty(status)) {
3229 IOVEC_SET_STRING(iovec[n++], "[");
3230 IOVEC_SET_STRING(iovec[n++], status);
3231 IOVEC_SET_STRING(iovec[n++], "] ");
3233 IOVEC_SET_STRING(iovec[n++], status_indent);
3236 IOVEC_SET_STRING(iovec[n++], s);
3237 IOVEC_SET_STRING(iovec[n++], "\n");
3239 if (writev(fd, iovec, n) < 0)
3245 int status_printf(const char *status, bool ellipse, const char *format, ...) {
3251 va_start(ap, format);
3252 r = status_vprintf(status, ellipse, format, ap);
3258 int status_welcome(void) {
3260 _cleanup_free_ char *pretty_name = NULL, *ansi_color = NULL;
3262 r = parse_env_file("/etc/os-release", NEWLINE,
3263 "PRETTY_NAME", &pretty_name,
3264 "ANSI_COLOR", &ansi_color,
3266 if (r < 0 && r != -ENOENT)
3267 log_warning("Failed to read /etc/os-release: %s", strerror(-r));
3269 return status_printf(NULL, false,
3270 "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
3271 isempty(ansi_color) ? "1" : ansi_color,
3272 isempty(pretty_name) ? "Linux" : pretty_name);
3275 char *replace_env(const char *format, char **env) {
3282 const char *e, *word = format;
3287 for (e = format; *e; e ++) {
3298 if (!(k = strnappend(r, word, e-word-1)))
3307 } else if (*e == '$') {
3308 if (!(k = strnappend(r, word, e-word)))
3324 if (!(t = strv_env_get_with_length(env, word+2, e-word-2)))
3327 if (!(k = strappend(r, t)))
3340 if (!(k = strnappend(r, word, e-word)))
3351 char **replace_env_argv(char **argv, char **env) {
3353 unsigned k = 0, l = 0;
3355 l = strv_length(argv);
3357 if (!(r = new(char*, l+1)))
3360 STRV_FOREACH(i, argv) {
3362 /* If $FOO appears as single word, replace it by the split up variable */
3363 if ((*i)[0] == '$' && (*i)[1] != '{') {
3368 if ((e = strv_env_get(env, *i+1))) {
3370 if (!(m = strv_split_quoted(e))) {
3381 if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
3390 memcpy(r + k, m, q * sizeof(char*));
3398 /* If ${FOO} appears as part of a word, replace it by the variable as-is */
3399 if (!(r[k++] = replace_env(*i, env))) {
3409 int fd_columns(int fd) {
3413 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3422 unsigned columns(void) {
3426 if (_likely_(cached_columns > 0))
3427 return cached_columns;
3430 e = getenv("COLUMNS");
3435 c = fd_columns(STDOUT_FILENO);
3444 int fd_lines(int fd) {
3448 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3457 unsigned lines(void) {
3461 if (_likely_(cached_lines > 0))
3462 return cached_lines;
3465 e = getenv("LINES");
3470 l = fd_lines(STDOUT_FILENO);
3476 return cached_lines;
3479 /* intended to be used as a SIGWINCH sighandler */
3480 void columns_lines_cache_reset(int signum) {
3486 static int cached_on_tty = -1;
3488 if (_unlikely_(cached_on_tty < 0))
3489 cached_on_tty = isatty(STDOUT_FILENO) > 0;
3491 return cached_on_tty;
3494 int running_in_chroot(void) {
3500 /* Only works as root */
3502 if (stat("/proc/1/root", &a) < 0)
3505 if (stat("/", &b) < 0)
3509 a.st_dev != b.st_dev ||
3510 a.st_ino != b.st_ino;
3513 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
3518 assert(percent <= 100);
3519 assert(new_length >= 3);
3521 if (old_length <= 3 || old_length <= new_length)
3522 return strndup(s, old_length);
3524 r = new0(char, new_length+1);
3528 x = (new_length * percent) / 100;
3530 if (x > new_length - 3)
3538 s + old_length - (new_length - x - 3),
3539 new_length - x - 3);
3544 char *ellipsize(const char *s, size_t length, unsigned percent) {
3545 return ellipsize_mem(s, strlen(s), length, percent);
3548 int touch(const char *path) {
3553 /* This just opens the file for writing, ensuring it
3554 * exists. It doesn't call utimensat() the way /usr/bin/touch
3557 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644);
3561 close_nointr_nofail(fd);
3565 char *unquote(const char *s, const char* quotes) {
3569 /* This is rather stupid, simply removes the heading and
3570 * trailing quotes if there is one. Doesn't care about
3571 * escaping or anything. We should make this smarter one
3578 if (strchr(quotes, s[0]) && s[l-1] == s[0])
3579 return strndup(s+1, l-2);
3584 char *normalize_env_assignment(const char *s) {
3585 _cleanup_free_ char *name = NULL, *value = NULL, *p = NULL;
3588 eq = strchr(s, '=');
3600 memmove(r, t, strlen(t) + 1);
3604 name = strndup(s, eq - s);
3612 value = unquote(strstrip(p), QUOTES);
3616 if (asprintf(&r, "%s=%s", strstrip(name), value) < 0)
3622 int wait_for_terminate(pid_t pid, siginfo_t *status) {
3633 if (waitid(P_PID, pid, status, WEXITED) < 0) {
3645 int wait_for_terminate_and_warn(const char *name, pid_t pid) {
3652 r = wait_for_terminate(pid, &status);
3654 log_warning("Failed to wait for %s: %s", name, strerror(-r));
3658 if (status.si_code == CLD_EXITED) {
3659 if (status.si_status != 0) {
3660 log_warning("%s failed with error code %i.", name, status.si_status);
3661 return status.si_status;
3664 log_debug("%s succeeded.", name);
3667 } else if (status.si_code == CLD_KILLED ||
3668 status.si_code == CLD_DUMPED) {
3670 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
3674 log_warning("%s failed due to unknown reason.", name);
3678 _noreturn_ void freeze(void) {
3680 /* Make sure nobody waits for us on a socket anymore */
3681 close_all_fds(NULL, 0);
3689 bool null_or_empty(struct stat *st) {
3692 if (S_ISREG(st->st_mode) && st->st_size <= 0)
3695 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
3701 int null_or_empty_path(const char *fn) {
3706 if (stat(fn, &st) < 0)
3709 return null_or_empty(&st);
3712 DIR *xopendirat(int fd, const char *name, int flags) {
3716 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags);
3722 close_nointr_nofail(nfd);
3729 int signal_from_string_try_harder(const char *s) {
3733 signo = signal_from_string(s);
3735 if (startswith(s, "SIG"))
3736 return signal_from_string(s+3);
3741 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
3745 /* FIXME: to follow udev's logic 100% we need to leave valid
3746 * UTF8 chars unescaped */
3748 u = unquote(tagvalue, "\"\'");
3752 t = xescape(u, "/ ");
3758 r = asprintf(&dn, "/dev/disk/by-%s/%s", by, t);
3767 char *fstab_node_to_udev_node(const char *p) {
3770 if (startswith(p, "LABEL="))
3771 return tag_to_udev_node(p+6, "label");
3773 if (startswith(p, "UUID="))
3774 return tag_to_udev_node(p+5, "uuid");
3776 if (startswith(p, "PARTUUID="))
3777 return tag_to_udev_node(p+9, "partuuid");
3779 if (startswith(p, "PARTLABEL="))
3780 return tag_to_udev_node(p+10, "partlabel");
3785 bool tty_is_vc(const char *tty) {
3788 if (startswith(tty, "/dev/"))
3791 return vtnr_from_tty(tty) >= 0;
3794 bool tty_is_console(const char *tty) {
3797 if (startswith(tty, "/dev/"))
3800 return streq(tty, "console");
3803 int vtnr_from_tty(const char *tty) {
3808 if (startswith(tty, "/dev/"))
3811 if (!startswith(tty, "tty") )
3814 if (tty[3] < '0' || tty[3] > '9')
3817 r = safe_atoi(tty+3, &i);
3821 if (i < 0 || i > 63)
3827 bool tty_is_vc_resolve(const char *tty) {
3828 char *active = NULL;
3833 if (startswith(tty, "/dev/"))
3836 /* Resolve where /dev/console is pointing to, if /sys is
3837 * actually ours (i.e. not read-only-mounted which is a sign
3838 * for container setups) */
3839 if (streq(tty, "console") && path_is_read_only_fs("/sys") <= 0)
3840 if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) {
3841 /* If multiple log outputs are configured the
3842 * last one is what /dev/console points to */
3843 tty = strrchr(active, ' ');
3856 const char *default_term_for_tty(const char *tty) {
3859 return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102";
3862 bool dirent_is_file(const struct dirent *de) {
3865 if (ignore_file(de->d_name))
3868 if (de->d_type != DT_REG &&
3869 de->d_type != DT_LNK &&
3870 de->d_type != DT_UNKNOWN)
3876 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
3879 if (de->d_type != DT_REG &&
3880 de->d_type != DT_LNK &&
3881 de->d_type != DT_UNKNOWN)
3884 if (ignore_file_allow_backup(de->d_name))
3887 return endswith(de->d_name, suffix);
3890 void execute_directory(const char *directory, DIR *d, char *argv[]) {
3893 Hashmap *pids = NULL;
3897 /* Executes all binaries in a directory in parallel and waits
3898 * until all they all finished. */
3901 if (!(_d = opendir(directory))) {
3903 if (errno == ENOENT)
3906 log_error("Failed to enumerate directory %s: %m", directory);
3913 if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) {
3914 log_error("Failed to allocate set.");
3918 while ((de = readdir(d))) {
3923 if (!dirent_is_file(de))
3926 if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
3931 if ((pid = fork()) < 0) {
3932 log_error("Failed to fork: %m");
3950 log_error("Failed to execute %s: %m", path);
3951 _exit(EXIT_FAILURE);
3954 log_debug("Spawned %s as %lu", path, (unsigned long) pid);
3956 if ((k = hashmap_put(pids, UINT_TO_PTR(pid), path)) < 0) {
3957 log_error("Failed to add PID to set: %s", strerror(-k));
3962 while (!hashmap_isempty(pids)) {
3963 pid_t pid = PTR_TO_UINT(hashmap_first_key(pids));
3968 if (waitid(P_PID, pid, &si, WEXITED) < 0) {
3973 log_error("waitid() failed: %m");
3977 if ((path = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) {
3978 if (!is_clean_exit(si.si_code, si.si_status, NULL)) {
3979 if (si.si_code == CLD_EXITED)
3980 log_error("%s exited with exit status %i.", path, si.si_status);
3982 log_error("%s terminated by signal %s.", path, signal_to_string(si.si_status));
3984 log_debug("%s exited successfully.", path);
3995 hashmap_free_free(pids);
3998 int kill_and_sigcont(pid_t pid, int sig) {
4001 r = kill(pid, sig) < 0 ? -errno : 0;
4009 bool nulstr_contains(const char*nulstr, const char *needle) {
4015 NULSTR_FOREACH(i, nulstr)
4016 if (streq(i, needle))
4022 bool plymouth_running(void) {
4023 return access("/run/plymouth/pid", F_OK) >= 0;
4026 char* strshorten(char *s, size_t l) {
4035 static bool hostname_valid_char(char c) {
4037 (c >= 'a' && c <= 'z') ||
4038 (c >= 'A' && c <= 'Z') ||
4039 (c >= '0' && c <= '9') ||
4045 bool hostname_is_valid(const char *s) {
4051 for (p = s; *p; p++)
4052 if (!hostname_valid_char(*p))
4055 if (p-s > HOST_NAME_MAX)
4061 char* hostname_cleanup(char *s) {
4064 for (p = s, d = s; *p; p++)
4065 if ((*p >= 'a' && *p <= 'z') ||
4066 (*p >= 'A' && *p <= 'Z') ||
4067 (*p >= '0' && *p <= '9') ||
4075 strshorten(s, HOST_NAME_MAX);
4079 int pipe_eof(int fd) {
4080 struct pollfd pollfd;
4085 pollfd.events = POLLIN|POLLHUP;
4087 r = poll(&pollfd, 1, 0);
4094 return pollfd.revents & POLLHUP;
4097 int fd_wait_for_event(int fd, int event, usec_t t) {
4098 struct pollfd pollfd;
4103 pollfd.events = event;
4105 r = poll(&pollfd, 1, t == (usec_t) -1 ? -1 : (int) (t / USEC_PER_MSEC));
4112 return pollfd.revents;
4115 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
4126 t = new(char, strlen(path) + 1 + 6 + 1);
4130 fn = path_get_file_name(path);
4134 stpcpy(stpcpy(t+k+1, fn), "XXXXXX");
4136 fd = mkostemp(t, O_WRONLY|O_CLOEXEC);
4142 f = fdopen(fd, "we");
4155 int terminal_vhangup_fd(int fd) {
4158 if (ioctl(fd, TIOCVHANGUP) < 0)
4164 int terminal_vhangup(const char *name) {
4167 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4171 r = terminal_vhangup_fd(fd);
4172 close_nointr_nofail(fd);
4177 int vt_disallocate(const char *name) {
4181 /* Deallocate the VT if possible. If not possible
4182 * (i.e. because it is the active one), at least clear it
4183 * entirely (including the scrollback buffer) */
4185 if (!startswith(name, "/dev/"))
4188 if (!tty_is_vc(name)) {
4189 /* So this is not a VT. I guess we cannot deallocate
4190 * it then. But let's at least clear the screen */
4192 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4197 "\033[r" /* clear scrolling region */
4198 "\033[H" /* move home */
4199 "\033[2J", /* clear screen */
4201 close_nointr_nofail(fd);
4206 if (!startswith(name, "/dev/tty"))
4209 r = safe_atou(name+8, &u);
4216 /* Try to deallocate */
4217 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
4221 r = ioctl(fd, VT_DISALLOCATE, u);
4222 close_nointr_nofail(fd);
4230 /* Couldn't deallocate, so let's clear it fully with
4232 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4237 "\033[r" /* clear scrolling region */
4238 "\033[H" /* move home */
4239 "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
4241 close_nointr_nofail(fd);
4246 int copy_file(const char *from, const char *to) {
4252 fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
4256 fdt = open(to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY, 0644);
4258 close_nointr_nofail(fdf);
4266 n = read(fdf, buf, sizeof(buf));
4270 close_nointr_nofail(fdf);
4281 k = loop_write(fdt, buf, n, false);
4283 r = k < 0 ? k : (errno ? -errno : -EIO);
4285 close_nointr_nofail(fdf);
4293 close_nointr_nofail(fdf);
4294 r = close_nointr(fdt);
4304 int symlink_atomic(const char *from, const char *to) {
4306 _cleanup_free_ char *t;
4309 unsigned long long ull;
4316 t = new(char, strlen(to) + 1 + 16 + 1);
4320 fn = path_get_file_name(to);
4324 x = stpcpy(t+k+1, fn);
4327 for (i = 0; i < 16; i++) {
4328 *(x++) = hexchar(ull & 0xF);
4334 if (symlink(from, t) < 0)
4337 if (rename(t, to) < 0) {
4346 bool display_is_local(const char *display) {
4350 display[0] == ':' &&
4351 display[1] >= '0' &&
4355 int socket_from_display(const char *display, char **path) {
4362 if (!display_is_local(display))
4365 k = strspn(display+1, "0123456789");
4367 f = new(char, sizeof("/tmp/.X11-unix/X") + k);
4371 c = stpcpy(f, "/tmp/.X11-unix/X");
4372 memcpy(c, display+1, k);
4381 const char **username,
4382 uid_t *uid, gid_t *gid,
4384 const char **shell) {
4392 /* We enforce some special rules for uid=0: in order to avoid
4393 * NSS lookups for root we hardcode its data. */
4395 if (streq(*username, "root") || streq(*username, "0")) {
4413 if (parse_uid(*username, &u) >= 0) {
4417 /* If there are multiple users with the same id, make
4418 * sure to leave $USER to the configured value instead
4419 * of the first occurrence in the database. However if
4420 * the uid was configured by a numeric uid, then let's
4421 * pick the real username from /etc/passwd. */
4423 *username = p->pw_name;
4426 p = getpwnam(*username);
4430 return errno != 0 ? -errno : -ESRCH;
4442 *shell = p->pw_shell;
4447 char* uid_to_name(uid_t uid) {
4452 return strdup("root");
4456 return strdup(p->pw_name);
4458 if (asprintf(&r, "%lu", (unsigned long) uid) < 0)
4464 int get_group_creds(const char **groupname, gid_t *gid) {
4470 /* We enforce some special rules for gid=0: in order to avoid
4471 * NSS lookups for root we hardcode its data. */
4473 if (streq(*groupname, "root") || streq(*groupname, "0")) {
4474 *groupname = "root";
4482 if (parse_gid(*groupname, &id) >= 0) {
4487 *groupname = g->gr_name;
4490 g = getgrnam(*groupname);
4494 return errno != 0 ? -errno : -ESRCH;
4502 int in_group(const char *name) {
4504 int ngroups_max, r, i;
4506 r = get_group_creds(&name, &gid);
4510 if (getgid() == gid)
4513 if (getegid() == gid)
4516 ngroups_max = sysconf(_SC_NGROUPS_MAX);
4517 assert(ngroups_max > 0);
4519 gids = alloca(sizeof(gid_t) * ngroups_max);
4521 r = getgroups(ngroups_max, gids);
4525 for (i = 0; i < r; i++)
4532 int glob_exists(const char *path) {
4540 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
4542 if (k == GLOB_NOMATCH)
4544 else if (k == GLOB_NOSPACE)
4547 r = !strv_isempty(g.gl_pathv);
4549 r = errno ? -errno : -EIO;
4556 int dirent_ensure_type(DIR *d, struct dirent *de) {
4562 if (de->d_type != DT_UNKNOWN)
4565 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
4569 S_ISREG(st.st_mode) ? DT_REG :
4570 S_ISDIR(st.st_mode) ? DT_DIR :
4571 S_ISLNK(st.st_mode) ? DT_LNK :
4572 S_ISFIFO(st.st_mode) ? DT_FIFO :
4573 S_ISSOCK(st.st_mode) ? DT_SOCK :
4574 S_ISCHR(st.st_mode) ? DT_CHR :
4575 S_ISBLK(st.st_mode) ? DT_BLK :
4581 int in_search_path(const char *path, char **search) {
4585 r = path_get_parent(path, &parent);
4591 STRV_FOREACH(i, search) {
4592 if (path_equal(parent, *i)) {
4603 int get_files_in_directory(const char *path, char ***list) {
4611 /* Returns all files in a directory in *list, and the number
4612 * of files as return value. If list is NULL returns only the
4621 union dirent_storage buf;
4624 k = readdir_r(d, &buf.de, &de);
4633 dirent_ensure_type(d, de);
4635 if (!dirent_is_file(de))
4639 if ((unsigned) r >= n) {
4643 t = realloc(l, sizeof(char*) * n);
4652 assert((unsigned) r < n);
4654 l[r] = strdup(de->d_name);
4678 char *strjoin(const char *x, ...) {
4692 t = va_arg(ap, const char *);
4697 if (n > ((size_t) -1) - l) {
4721 t = va_arg(ap, const char *);
4735 bool is_main_thread(void) {
4736 static __thread int cached = 0;
4738 if (_unlikely_(cached == 0))
4739 cached = getpid() == gettid() ? 1 : -1;
4744 int block_get_whole_disk(dev_t d, dev_t *ret) {
4751 /* If it has a queue this is good enough for us */
4752 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
4755 r = access(p, F_OK);
4763 /* If it is a partition find the originating device */
4764 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
4767 r = access(p, F_OK);
4773 /* Get parent dev_t */
4774 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
4777 r = read_one_line_file(p, &s);
4783 r = sscanf(s, "%u:%u", &m, &n);
4789 /* Only return this if it is really good enough for us. */
4790 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
4793 r = access(p, F_OK);
4797 *ret = makedev(m, n);
4804 int file_is_priv_sticky(const char *p) {
4809 if (lstat(p, &st) < 0)
4813 (st.st_uid == 0 || st.st_uid == getuid()) &&
4814 (st.st_mode & S_ISVTX);
4817 static const char *const ioprio_class_table[] = {
4818 [IOPRIO_CLASS_NONE] = "none",
4819 [IOPRIO_CLASS_RT] = "realtime",
4820 [IOPRIO_CLASS_BE] = "best-effort",
4821 [IOPRIO_CLASS_IDLE] = "idle"
4824 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
4826 static const char *const sigchld_code_table[] = {
4827 [CLD_EXITED] = "exited",
4828 [CLD_KILLED] = "killed",
4829 [CLD_DUMPED] = "dumped",
4830 [CLD_TRAPPED] = "trapped",
4831 [CLD_STOPPED] = "stopped",
4832 [CLD_CONTINUED] = "continued",
4835 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
4837 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
4838 [LOG_FAC(LOG_KERN)] = "kern",
4839 [LOG_FAC(LOG_USER)] = "user",
4840 [LOG_FAC(LOG_MAIL)] = "mail",
4841 [LOG_FAC(LOG_DAEMON)] = "daemon",
4842 [LOG_FAC(LOG_AUTH)] = "auth",
4843 [LOG_FAC(LOG_SYSLOG)] = "syslog",
4844 [LOG_FAC(LOG_LPR)] = "lpr",
4845 [LOG_FAC(LOG_NEWS)] = "news",
4846 [LOG_FAC(LOG_UUCP)] = "uucp",
4847 [LOG_FAC(LOG_CRON)] = "cron",
4848 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
4849 [LOG_FAC(LOG_FTP)] = "ftp",
4850 [LOG_FAC(LOG_LOCAL0)] = "local0",
4851 [LOG_FAC(LOG_LOCAL1)] = "local1",
4852 [LOG_FAC(LOG_LOCAL2)] = "local2",
4853 [LOG_FAC(LOG_LOCAL3)] = "local3",
4854 [LOG_FAC(LOG_LOCAL4)] = "local4",
4855 [LOG_FAC(LOG_LOCAL5)] = "local5",
4856 [LOG_FAC(LOG_LOCAL6)] = "local6",
4857 [LOG_FAC(LOG_LOCAL7)] = "local7"
4860 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
4862 static const char *const log_level_table[] = {
4863 [LOG_EMERG] = "emerg",
4864 [LOG_ALERT] = "alert",
4865 [LOG_CRIT] = "crit",
4867 [LOG_WARNING] = "warning",
4868 [LOG_NOTICE] = "notice",
4869 [LOG_INFO] = "info",
4870 [LOG_DEBUG] = "debug"
4873 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
4875 static const char* const sched_policy_table[] = {
4876 [SCHED_OTHER] = "other",
4877 [SCHED_BATCH] = "batch",
4878 [SCHED_IDLE] = "idle",
4879 [SCHED_FIFO] = "fifo",
4883 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
4885 static const char* const rlimit_table[] = {
4886 [RLIMIT_CPU] = "LimitCPU",
4887 [RLIMIT_FSIZE] = "LimitFSIZE",
4888 [RLIMIT_DATA] = "LimitDATA",
4889 [RLIMIT_STACK] = "LimitSTACK",
4890 [RLIMIT_CORE] = "LimitCORE",
4891 [RLIMIT_RSS] = "LimitRSS",
4892 [RLIMIT_NOFILE] = "LimitNOFILE",
4893 [RLIMIT_AS] = "LimitAS",
4894 [RLIMIT_NPROC] = "LimitNPROC",
4895 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
4896 [RLIMIT_LOCKS] = "LimitLOCKS",
4897 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
4898 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
4899 [RLIMIT_NICE] = "LimitNICE",
4900 [RLIMIT_RTPRIO] = "LimitRTPRIO",
4901 [RLIMIT_RTTIME] = "LimitRTTIME"
4904 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
4906 static const char* const ip_tos_table[] = {
4907 [IPTOS_LOWDELAY] = "low-delay",
4908 [IPTOS_THROUGHPUT] = "throughput",
4909 [IPTOS_RELIABILITY] = "reliability",
4910 [IPTOS_LOWCOST] = "low-cost",
4913 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
4915 static const char *const __signal_table[] = {
4932 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
4943 [SIGVTALRM] = "VTALRM",
4945 [SIGWINCH] = "WINCH",
4951 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
4953 const char *signal_to_string(int signo) {
4954 static __thread char buf[12];
4957 name = __signal_to_string(signo);
4961 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
4962 snprintf(buf, sizeof(buf) - 1, "RTMIN+%d", signo - SIGRTMIN);
4964 snprintf(buf, sizeof(buf) - 1, "%d", signo);
4969 int signal_from_string(const char *s) {
4974 signo = __signal_from_string(s);
4978 if (startswith(s, "RTMIN+")) {
4982 if (safe_atou(s, &u) >= 0) {
4983 signo = (int) u + offset;
4984 if (signo > 0 && signo < _NSIG)
4990 bool kexec_loaded(void) {
4991 bool loaded = false;
4994 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
5002 int strdup_or_null(const char *a, char **b) {
5020 int prot_from_flags(int flags) {
5022 switch (flags & O_ACCMODE) {
5031 return PROT_READ|PROT_WRITE;
5038 char *format_bytes(char *buf, size_t l, off_t t) {
5041 static const struct {
5045 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5046 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5047 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
5048 { "G", 1024ULL*1024ULL*1024ULL },
5049 { "M", 1024ULL*1024ULL },
5053 for (i = 0; i < ELEMENTSOF(table); i++) {
5055 if (t >= table[i].factor) {
5058 (unsigned long long) (t / table[i].factor),
5059 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
5066 snprintf(buf, l, "%lluB", (unsigned long long) t);
5074 void* memdup(const void *p, size_t l) {
5087 int fd_inc_sndbuf(int fd, size_t n) {
5089 socklen_t l = sizeof(value);
5091 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
5093 l == sizeof(value) &&
5094 (size_t) value >= n*2)
5098 r = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value));
5105 int fd_inc_rcvbuf(int fd, size_t n) {
5107 socklen_t l = sizeof(value);
5109 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
5111 l == sizeof(value) &&
5112 (size_t) value >= n*2)
5116 r = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value));
5123 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
5124 pid_t parent_pid, agent_pid;
5126 bool stdout_is_tty, stderr_is_tty;
5134 parent_pid = getpid();
5136 /* Spawns a temporary TTY agent, making sure it goes away when
5143 if (agent_pid != 0) {
5150 * Make sure the agent goes away when the parent dies */
5151 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
5152 _exit(EXIT_FAILURE);
5154 /* Check whether our parent died before we were able
5155 * to set the death signal */
5156 if (getppid() != parent_pid)
5157 _exit(EXIT_SUCCESS);
5159 /* Don't leak fds to the agent */
5160 close_all_fds(except, n_except);
5162 stdout_is_tty = isatty(STDOUT_FILENO);
5163 stderr_is_tty = isatty(STDERR_FILENO);
5165 if (!stdout_is_tty || !stderr_is_tty) {
5166 /* Detach from stdout/stderr. and reopen
5167 * /dev/tty for them. This is important to
5168 * ensure that when systemctl is started via
5169 * popen() or a similar call that expects to
5170 * read EOF we actually do generate EOF and
5171 * not delay this indefinitely by because we
5172 * keep an unused copy of stdin around. */
5173 fd = open("/dev/tty", O_WRONLY);
5175 log_error("Failed to open /dev/tty: %m");
5176 _exit(EXIT_FAILURE);
5180 dup2(fd, STDOUT_FILENO);
5183 dup2(fd, STDERR_FILENO);
5189 /* Count arguments */
5191 for (n = 0; va_arg(ap, char*); n++)
5196 l = alloca(sizeof(char *) * (n + 1));
5198 /* Fill in arguments */
5200 for (i = 0; i <= n; i++)
5201 l[i] = va_arg(ap, char*);
5205 _exit(EXIT_FAILURE);
5208 int setrlimit_closest(int resource, const struct rlimit *rlim) {
5209 struct rlimit highest, fixed;
5213 if (setrlimit(resource, rlim) >= 0)
5219 /* So we failed to set the desired setrlimit, then let's try
5220 * to get as close as we can */
5221 assert_se(getrlimit(resource, &highest) == 0);
5223 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
5224 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
5226 if (setrlimit(resource, &fixed) < 0)
5232 int getenv_for_pid(pid_t pid, const char *field, char **_value) {
5233 char path[sizeof("/proc/")-1+10+sizeof("/environ")], *value = NULL;
5245 snprintf(path, sizeof(path), "/proc/%lu/environ", (unsigned long) pid);
5248 f = fopen(path, "re");
5256 char line[LINE_MAX];
5259 for (i = 0; i < sizeof(line)-1; i++) {
5263 if (_unlikely_(c == EOF)) {
5273 if (memcmp(line, field, l) == 0 && line[l] == '=') {
5274 value = strdup(line + l + 1);
5294 int can_sleep(const char *type) {
5298 _cleanup_free_ char *p = NULL;
5302 /* If /sys is read-only we cannot sleep */
5303 if (access("/sys/power/state", W_OK) < 0)
5306 r = read_one_line_file("/sys/power/state", &p);
5311 FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state)
5312 if (l == k && memcmp(w, type, l) == 0)
5318 int can_sleep_disk(const char *type) {
5322 _cleanup_free_ char *p = NULL;
5326 /* If /sys is read-only we cannot sleep */
5327 if (access("/sys/power/state", W_OK) < 0 ||
5328 access("/sys/power/disk", W_OK) < 0)
5331 r = read_one_line_file("/sys/power/disk", &p);
5336 FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state) {
5337 if (l == k && memcmp(w, type, l) == 0)
5340 if (l == k + 2 && w[0] == '[' && memcmp(w + 1, type, l - 2) == 0 && w[l-1] == ']')
5347 bool is_valid_documentation_url(const char *url) {
5350 if (startswith(url, "http://") && url[7])
5353 if (startswith(url, "https://") && url[8])
5356 if (startswith(url, "file:") && url[5])
5359 if (startswith(url, "info:") && url[5])
5362 if (startswith(url, "man:") && url[4])
5368 bool in_initrd(void) {
5369 static __thread int saved = -1;
5375 /* We make two checks here:
5377 * 1. the flag file /etc/initrd-release must exist
5378 * 2. the root file system must be a memory file system
5380 * The second check is extra paranoia, since misdetecting an
5381 * initrd can have bad bad consequences due the initrd
5382 * emptying when transititioning to the main systemd.
5385 saved = access("/etc/initrd-release", F_OK) >= 0 &&
5386 statfs("/", &s) >= 0 &&
5387 is_temporary_fs(&s);
5392 void warn_melody(void) {
5393 _cleanup_close_ int fd = -1;
5395 fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
5399 /* Yeah, this is synchronous. Kinda sucks. But well... */
5401 ioctl(fd, KIOCSOUND, (int)(1193180/440));
5402 usleep(125*USEC_PER_MSEC);
5404 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5405 usleep(125*USEC_PER_MSEC);
5407 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5408 usleep(125*USEC_PER_MSEC);
5410 ioctl(fd, KIOCSOUND, 0);
5413 int make_console_stdio(void) {
5416 /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
5418 fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1);
5420 log_error("Failed to acquire terminal: %s", strerror(-fd));
5426 log_error("Failed to duplicate terminal fd: %s", strerror(-r));
5433 int get_home_dir(char **_h) {
5441 /* Take the user specified one */
5452 /* Hardcode home directory for root to avoid NSS */
5455 h = strdup("/root");
5463 /* Check the database... */
5467 return errno ? -errno : -ESRCH;
5469 if (!path_is_absolute(p->pw_dir))
5472 h = strdup(p->pw_dir);
5480 int get_shell(char **_sh) {
5488 /* Take the user specified one */
5489 e = getenv("SHELL");
5499 /* Hardcode home directory for root to avoid NSS */
5502 sh = strdup("/bin/sh");
5510 /* Check the database... */
5514 return errno ? -errno : -ESRCH;
5516 if (!path_is_absolute(p->pw_shell))
5519 sh = strdup(p->pw_shell);
5527 void freep(void *p) {
5531 void fclosep(FILE **f) {
5536 void closep(int *fd) {
5538 close_nointr_nofail(*fd);
5541 void closedirp(DIR **d) {
5546 void umaskp(mode_t *u) {
5550 bool filename_is_safe(const char *p) {
5564 if (strlen(p) > FILENAME_MAX)
5570 bool string_is_safe(const char *p) {
5575 for (t = p; *t; t++) {
5576 if (*t > 0 && *t < ' ')
5579 if (strchr("\\\"\'", *t))
5586 /* hey glibc, APIs with callbacks without a user pointer are so useless */
5587 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
5588 int (*compar) (const void *, const void *, void *), void *arg) {
5597 p = (void *)(((const char *) base) + (idx * size));
5598 comparison = compar(key, p, arg);
5601 else if (comparison > 0)
5609 bool is_locale_utf8(void) {
5611 static int cached_answer = -1;
5613 if (cached_answer >= 0)
5616 if (!setlocale(LC_ALL, "")) {
5617 cached_answer = true;
5621 set = nl_langinfo(CODESET);
5623 cached_answer = true;
5627 cached_answer = streq(set, "UTF-8");
5629 return (bool)cached_answer;
5632 const char *draw_special_char(DrawSpecialChar ch) {
5633 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
5635 [DRAW_TREE_VERT] = "\342\224\202 ", /* │ */
5636 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
5637 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
5638 [DRAW_TRIANGULAR_BULLET] = "\342\200\243 ", /* ‣ */
5640 /* ASCII fallback */ {
5641 [DRAW_TREE_VERT] = "| ",
5642 [DRAW_TREE_BRANCH] = "|-",
5643 [DRAW_TREE_RIGHT] = "`-",
5644 [DRAW_TRIANGULAR_BULLET] = "> ",
5648 return draw_table[!is_locale_utf8()][ch];
5651 char *strreplace(const char *text, const char *old_string, const char *new_string) {
5654 size_t l, old_len, new_len;
5660 old_len = strlen(old_string);
5661 new_len = strlen(new_string);
5674 if (!startswith(f, old_string)) {
5680 nl = l - old_len + new_len;
5681 a = realloc(r, nl + 1);
5689 t = stpcpy(t, new_string);
5701 char *strip_tab_ansi(char **ibuf, size_t *_isz) {
5702 const char *i, *begin = NULL;
5707 } state = STATE_OTHER;
5709 size_t osz = 0, isz;
5715 /* Strips ANSI color and replaces TABs by 8 spaces */
5717 isz = _isz ? *_isz : strlen(*ibuf);
5719 f = open_memstream(&obuf, &osz);
5723 for (i = *ibuf; i < *ibuf + isz + 1; i++) {
5728 if (i >= *ibuf + isz) /* EOT */
5730 else if (*i == '\x1B')
5731 state = STATE_ESCAPE;
5732 else if (*i == '\t')
5739 if (i >= *ibuf + isz) { /* EOT */
5742 } else if (*i == '[') {
5743 state = STATE_BRACKET;
5748 state = STATE_OTHER;
5755 if (i >= *ibuf + isz || /* EOT */
5756 (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
5759 state = STATE_OTHER;
5761 } else if (*i == 'm')
5762 state = STATE_OTHER;
5784 int on_ac_power(void) {
5785 bool found_offline = false, found_online = false;
5786 _cleanup_closedir_ DIR *d = NULL;
5788 d = opendir("/sys/class/power_supply");
5794 union dirent_storage buf;
5795 _cleanup_free_ char *p = NULL;
5796 _cleanup_close_ int fd = -1, device = -1;
5801 k = readdir_r(d, &buf.de, &de);
5808 if (ignore_file(de->d_name))
5811 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
5813 if (errno == ENOENT || errno == ENOTDIR)
5819 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
5821 if (errno == ENOENT)
5827 n = read(fd, contents, sizeof(contents));
5831 if (n != 6 || memcmp(contents, "Mains\n", 6))
5834 close_nointr_nofail(fd);
5835 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
5837 if (errno == ENOENT)
5843 n = read(fd, contents, sizeof(contents));
5847 if (n != 2 || contents[1] != '\n')
5850 if (contents[0] == '1') {
5851 found_online = true;
5853 } else if (contents[0] == '0')
5854 found_offline = true;
5859 return found_online || !found_offline;