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) {
915 f = fopen("/proc/self/cmdline", "re");
918 if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
927 if (max_length == 0) {
929 while ((c = getc(f)) != EOF) {
930 k = realloc(r, len+1);
937 r[len-1] = isprint(c) ? c : ' ';
944 r = new(char, max_length);
952 while ((c = getc(f)) != EOF) {
974 size_t n = MIN(left-1, 3U);
983 /* Kernel threads have no argv[] */
984 if (r == NULL || r[0] == 0) {
993 h = get_process_comm(pid, &t);
997 r = strjoin("[", t, "]", NULL);
1008 int is_kernel_thread(pid_t pid) {
1018 if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
1027 count = fread(&c, 1, 1, f);
1031 /* Kernel threads have an empty cmdline */
1034 return eof ? 1 : -errno;
1039 int get_process_exe(pid_t pid, char **name) {
1045 r = readlink_malloc("/proc/self/exe", name);
1048 if (asprintf(&p, "/proc/%lu/exe", (unsigned long) pid) < 0)
1051 r = readlink_malloc(p, name);
1058 static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
1068 if (asprintf(&p, "/proc/%lu/status", (unsigned long) pid) < 0)
1078 char line[LINE_MAX], *l;
1080 if (!fgets(line, sizeof(line), f)) {
1090 if (startswith(l, field)) {
1092 l += strspn(l, WHITESPACE);
1094 l[strcspn(l, WHITESPACE)] = 0;
1096 r = parse_uid(l, uid);
1109 int get_process_uid(pid_t pid, uid_t *uid) {
1110 return get_process_id(pid, "Uid:", uid);
1113 int get_process_gid(pid_t pid, gid_t *gid) {
1114 return get_process_id(pid, "Gid:", gid);
1117 char *strnappend(const char *s, const char *suffix, size_t b) {
1125 return strndup(suffix, b);
1134 if (b > ((size_t) -1) - a)
1137 r = new(char, a+b+1);
1142 memcpy(r+a, suffix, b);
1148 char *strappend(const char *s, const char *suffix) {
1149 return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
1152 int readlink_malloc(const char *p, char **r) {
1162 if (!(c = new(char, l)))
1165 if ((n = readlink(p, c, l-1)) < 0) {
1171 if ((size_t) n < l-1) {
1182 int readlink_and_make_absolute(const char *p, char **r) {
1189 if ((j = readlink_malloc(p, &target)) < 0)
1192 k = file_in_same_dir(p, target);
1202 int readlink_and_canonicalize(const char *p, char **r) {
1209 j = readlink_and_make_absolute(p, &t);
1213 s = canonicalize_file_name(t);
1220 path_kill_slashes(*r);
1225 int reset_all_signal_handlers(void) {
1228 for (sig = 1; sig < _NSIG; sig++) {
1229 struct sigaction sa;
1231 if (sig == SIGKILL || sig == SIGSTOP)
1235 sa.sa_handler = SIG_DFL;
1236 sa.sa_flags = SA_RESTART;
1238 /* On Linux the first two RT signals are reserved by
1239 * glibc, and sigaction() will return EINVAL for them. */
1240 if ((sigaction(sig, &sa, NULL) < 0))
1241 if (errno != EINVAL)
1248 char *strstrip(char *s) {
1251 /* Drops trailing whitespace. Modifies the string in
1252 * place. Returns pointer to first non-space character */
1254 s += strspn(s, WHITESPACE);
1256 for (e = strchr(s, 0); e > s; e --)
1257 if (!strchr(WHITESPACE, e[-1]))
1265 char *delete_chars(char *s, const char *bad) {
1268 /* Drops all whitespace, regardless where in the string */
1270 for (f = s, t = s; *f; f++) {
1271 if (strchr(bad, *f))
1282 bool in_charset(const char *s, const char* charset) {
1288 for (i = s; *i; i++)
1289 if (!strchr(charset, *i))
1295 char *file_in_same_dir(const char *path, const char *filename) {
1302 /* This removes the last component of path and appends
1303 * filename, unless the latter is absolute anyway or the
1306 if (path_is_absolute(filename))
1307 return strdup(filename);
1309 if (!(e = strrchr(path, '/')))
1310 return strdup(filename);
1312 k = strlen(filename);
1313 if (!(r = new(char, e-path+1+k+1)))
1316 memcpy(r, path, e-path+1);
1317 memcpy(r+(e-path)+1, filename, k+1);
1322 int rmdir_parents(const char *path, const char *stop) {
1331 /* Skip trailing slashes */
1332 while (l > 0 && path[l-1] == '/')
1338 /* Skip last component */
1339 while (l > 0 && path[l-1] != '/')
1342 /* Skip trailing slashes */
1343 while (l > 0 && path[l-1] == '/')
1349 if (!(t = strndup(path, l)))
1352 if (path_startswith(stop, t)) {
1361 if (errno != ENOENT)
1369 char hexchar(int x) {
1370 static const char table[16] = "0123456789abcdef";
1372 return table[x & 15];
1375 int unhexchar(char c) {
1377 if (c >= '0' && c <= '9')
1380 if (c >= 'a' && c <= 'f')
1381 return c - 'a' + 10;
1383 if (c >= 'A' && c <= 'F')
1384 return c - 'A' + 10;
1389 char octchar(int x) {
1390 return '0' + (x & 7);
1393 int unoctchar(char c) {
1395 if (c >= '0' && c <= '7')
1401 char decchar(int x) {
1402 return '0' + (x % 10);
1405 int undecchar(char c) {
1407 if (c >= '0' && c <= '9')
1413 char *cescape(const char *s) {
1419 /* Does C style string escaping. */
1421 r = new(char, strlen(s)*4 + 1);
1425 for (f = s, t = r; *f; f++)
1471 /* For special chars we prefer octal over
1472 * hexadecimal encoding, simply because glib's
1473 * g_strescape() does the same */
1474 if ((*f < ' ') || (*f >= 127)) {
1476 *(t++) = octchar((unsigned char) *f >> 6);
1477 *(t++) = octchar((unsigned char) *f >> 3);
1478 *(t++) = octchar((unsigned char) *f);
1489 char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix) {
1496 /* Undoes C style string escaping, and optionally prefixes it. */
1498 pl = prefix ? strlen(prefix) : 0;
1500 r = new(char, pl+length+1);
1505 memcpy(r, prefix, pl);
1507 for (f = s, t = r + pl; f < s + length; f++) {
1550 /* This is an extension of the XDG syntax files */
1555 /* hexadecimal encoding */
1558 a = unhexchar(f[1]);
1559 b = unhexchar(f[2]);
1561 if (a < 0 || b < 0) {
1562 /* Invalid escape code, let's take it literal then */
1566 *(t++) = (char) ((a << 4) | b);
1581 /* octal encoding */
1584 a = unoctchar(f[0]);
1585 b = unoctchar(f[1]);
1586 c = unoctchar(f[2]);
1588 if (a < 0 || b < 0 || c < 0) {
1589 /* Invalid escape code, let's take it literal then */
1593 *(t++) = (char) ((a << 6) | (b << 3) | c);
1601 /* premature end of string.*/
1606 /* Invalid escape code, let's take it literal then */
1618 char *cunescape_length(const char *s, size_t length) {
1619 return cunescape_length_with_prefix(s, length, NULL);
1622 char *cunescape(const char *s) {
1625 return cunescape_length(s, strlen(s));
1628 char *xescape(const char *s, const char *bad) {
1632 /* Escapes all chars in bad, in addition to \ and all special
1633 * chars, in \xFF style escaping. May be reversed with
1636 r = new(char, strlen(s) * 4 + 1);
1640 for (f = s, t = r; *f; f++) {
1642 if ((*f < ' ') || (*f >= 127) ||
1643 (*f == '\\') || strchr(bad, *f)) {
1646 *(t++) = hexchar(*f >> 4);
1647 *(t++) = hexchar(*f);
1657 char *bus_path_escape(const char *s) {
1663 /* Escapes all chars that D-Bus' object path cannot deal
1664 * with. Can be reverse with bus_path_unescape() */
1666 if (!(r = new(char, strlen(s)*3+1)))
1669 for (f = s, t = r; *f; f++) {
1671 if (!(*f >= 'A' && *f <= 'Z') &&
1672 !(*f >= 'a' && *f <= 'z') &&
1673 !(*f >= '0' && *f <= '9')) {
1675 *(t++) = hexchar(*f >> 4);
1676 *(t++) = hexchar(*f);
1686 char *bus_path_unescape(const char *f) {
1691 if (!(r = strdup(f)))
1694 for (t = r; *f; f++) {
1699 if ((a = unhexchar(f[1])) < 0 ||
1700 (b = unhexchar(f[2])) < 0) {
1701 /* Invalid escape code, let's take it literal then */
1704 *(t++) = (char) ((a << 4) | b);
1716 char *ascii_strlower(char *t) {
1721 for (p = t; *p; p++)
1722 if (*p >= 'A' && *p <= 'Z')
1723 *p = *p - 'A' + 'a';
1728 static bool ignore_file_allow_backup(const char *filename) {
1732 filename[0] == '.' ||
1733 streq(filename, "lost+found") ||
1734 streq(filename, "aquota.user") ||
1735 streq(filename, "aquota.group") ||
1736 endswith(filename, ".rpmnew") ||
1737 endswith(filename, ".rpmsave") ||
1738 endswith(filename, ".rpmorig") ||
1739 endswith(filename, ".dpkg-old") ||
1740 endswith(filename, ".dpkg-new") ||
1741 endswith(filename, ".swp");
1744 bool ignore_file(const char *filename) {
1747 if (endswith(filename, "~"))
1750 return ignore_file_allow_backup(filename);
1753 int fd_nonblock(int fd, bool nonblock) {
1758 if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
1762 flags |= O_NONBLOCK;
1764 flags &= ~O_NONBLOCK;
1766 if (fcntl(fd, F_SETFL, flags) < 0)
1772 int fd_cloexec(int fd, bool cloexec) {
1777 if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
1781 flags |= FD_CLOEXEC;
1783 flags &= ~FD_CLOEXEC;
1785 if (fcntl(fd, F_SETFD, flags) < 0)
1791 static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
1794 assert(n_fdset == 0 || fdset);
1796 for (i = 0; i < n_fdset; i++)
1803 int close_all_fds(const int except[], unsigned n_except) {
1808 assert(n_except == 0 || except);
1810 d = opendir("/proc/self/fd");
1815 /* When /proc isn't available (for example in chroots)
1816 * the fallback is brute forcing through the fd
1819 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
1820 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
1822 if (fd_in_set(fd, except, n_except))
1825 if (close_nointr(fd) < 0)
1826 if (errno != EBADF && r == 0)
1833 while ((de = readdir(d))) {
1836 if (ignore_file(de->d_name))
1839 if (safe_atoi(de->d_name, &fd) < 0)
1840 /* Let's better ignore this, just in case */
1849 if (fd_in_set(fd, except, n_except))
1852 if (close_nointr(fd) < 0) {
1853 /* Valgrind has its own FD and doesn't want to have it closed */
1854 if (errno != EBADF && r == 0)
1863 bool chars_intersect(const char *a, const char *b) {
1866 /* Returns true if any of the chars in a are in b. */
1867 for (p = a; *p; p++)
1874 bool fstype_is_network(const char *fstype) {
1875 static const char table[] =
1884 return nulstr_contains(table, fstype);
1888 _cleanup_close_ int fd;
1890 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
1896 TIOCL_GETKMSGREDIRECT,
1900 if (ioctl(fd, TIOCLINUX, tiocl) < 0)
1903 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
1906 if (ioctl(fd, VT_ACTIVATE, vt) < 0)
1912 int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
1913 struct termios old_termios, new_termios;
1915 char line[LINE_MAX];
1920 if (tcgetattr(fileno(f), &old_termios) >= 0) {
1921 new_termios = old_termios;
1923 new_termios.c_lflag &= ~ICANON;
1924 new_termios.c_cc[VMIN] = 1;
1925 new_termios.c_cc[VTIME] = 0;
1927 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
1930 if (t != (usec_t) -1) {
1931 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
1932 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
1937 k = fread(&c, 1, 1, f);
1939 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
1945 *need_nl = c != '\n';
1952 if (t != (usec_t) -1)
1953 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
1956 if (!fgets(line, sizeof(line), f))
1961 if (strlen(line) != 1)
1971 int ask(char *ret, const char *replies, const char *text, ...) {
1981 bool need_nl = true;
1984 fputs(ANSI_HIGHLIGHT_ON, stdout);
1991 fputs(ANSI_HIGHLIGHT_OFF, stdout);
1995 r = read_one_char(stdin, &c, (usec_t) -1, &need_nl);
1998 if (r == -EBADMSG) {
1999 puts("Bad input, please try again.");
2010 if (strchr(replies, c)) {
2015 puts("Read unexpected character, please try again.");
2019 int reset_terminal_fd(int fd, bool switch_to_text) {
2020 struct termios termios;
2023 /* Set terminal to some sane defaults */
2027 /* We leave locked terminal attributes untouched, so that
2028 * Plymouth may set whatever it wants to set, and we don't
2029 * interfere with that. */
2031 /* Disable exclusive mode, just in case */
2032 ioctl(fd, TIOCNXCL);
2034 /* Switch to text mode */
2036 ioctl(fd, KDSETMODE, KD_TEXT);
2038 /* Enable console unicode mode */
2039 ioctl(fd, KDSKBMODE, K_UNICODE);
2041 if (tcgetattr(fd, &termios) < 0) {
2046 /* We only reset the stuff that matters to the software. How
2047 * hardware is set up we don't touch assuming that somebody
2048 * else will do that for us */
2050 termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
2051 termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
2052 termios.c_oflag |= ONLCR;
2053 termios.c_cflag |= CREAD;
2054 termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
2056 termios.c_cc[VINTR] = 03; /* ^C */
2057 termios.c_cc[VQUIT] = 034; /* ^\ */
2058 termios.c_cc[VERASE] = 0177;
2059 termios.c_cc[VKILL] = 025; /* ^X */
2060 termios.c_cc[VEOF] = 04; /* ^D */
2061 termios.c_cc[VSTART] = 021; /* ^Q */
2062 termios.c_cc[VSTOP] = 023; /* ^S */
2063 termios.c_cc[VSUSP] = 032; /* ^Z */
2064 termios.c_cc[VLNEXT] = 026; /* ^V */
2065 termios.c_cc[VWERASE] = 027; /* ^W */
2066 termios.c_cc[VREPRINT] = 022; /* ^R */
2067 termios.c_cc[VEOL] = 0;
2068 termios.c_cc[VEOL2] = 0;
2070 termios.c_cc[VTIME] = 0;
2071 termios.c_cc[VMIN] = 1;
2073 if (tcsetattr(fd, TCSANOW, &termios) < 0)
2077 /* Just in case, flush all crap out */
2078 tcflush(fd, TCIOFLUSH);
2083 int reset_terminal(const char *name) {
2086 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2090 r = reset_terminal_fd(fd, true);
2091 close_nointr_nofail(fd);
2096 int open_terminal(const char *name, int mode) {
2101 * If a TTY is in the process of being closed opening it might
2102 * cause EIO. This is horribly awful, but unlikely to be
2103 * changed in the kernel. Hence we work around this problem by
2104 * retrying a couple of times.
2106 * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
2110 fd = open(name, mode);
2117 /* Max 1s in total */
2121 usleep(50 * USEC_PER_MSEC);
2130 close_nointr_nofail(fd);
2135 close_nointr_nofail(fd);
2142 int flush_fd(int fd) {
2143 struct pollfd pollfd;
2147 pollfd.events = POLLIN;
2154 if ((r = poll(&pollfd, 1, 0)) < 0) {
2165 if ((l = read(fd, buf, sizeof(buf))) < 0) {
2170 if (errno == EAGAIN)
2181 int acquire_terminal(
2185 bool ignore_tiocstty_eperm,
2188 int fd = -1, notify = -1, r = 0, wd = -1;
2190 struct sigaction sa_old, sa_new;
2194 /* We use inotify to be notified when the tty is closed. We
2195 * create the watch before checking if we can actually acquire
2196 * it, so that we don't lose any event.
2198 * Note: strictly speaking this actually watches for the
2199 * device being closed, it does *not* really watch whether a
2200 * tty loses its controlling process. However, unless some
2201 * rogue process uses TIOCNOTTY on /dev/tty *after* closing
2202 * its tty otherwise this will not become a problem. As long
2203 * as the administrator makes sure not configure any service
2204 * on the same tty as an untrusted user this should not be a
2205 * problem. (Which he probably should not do anyway.) */
2207 if (timeout != (usec_t) -1)
2208 ts = now(CLOCK_MONOTONIC);
2210 if (!fail && !force) {
2211 notify = inotify_init1(IN_CLOEXEC | (timeout != (usec_t) -1 ? IN_NONBLOCK : 0));
2217 wd = inotify_add_watch(notify, name, IN_CLOSE);
2226 r = flush_fd(notify);
2231 /* We pass here O_NOCTTY only so that we can check the return
2232 * value TIOCSCTTY and have a reliable way to figure out if we
2233 * successfully became the controlling process of the tty */
2234 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2238 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2239 * if we already own the tty. */
2241 sa_new.sa_handler = SIG_IGN;
2242 sa_new.sa_flags = SA_RESTART;
2243 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2245 /* First, try to get the tty */
2246 if (ioctl(fd, TIOCSCTTY, force) < 0)
2249 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2251 /* Sometimes it makes sense to ignore TIOCSCTTY
2252 * returning EPERM, i.e. when very likely we already
2253 * are have this controlling terminal. */
2254 if (r < 0 && r == -EPERM && ignore_tiocstty_eperm)
2257 if (r < 0 && (force || fail || r != -EPERM)) {
2266 assert(notify >= 0);
2269 uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
2271 struct inotify_event *e;
2273 if (timeout != (usec_t) -1) {
2276 n = now(CLOCK_MONOTONIC);
2277 if (ts + timeout < n) {
2282 r = fd_wait_for_event(fd, POLLIN, ts + timeout - n);
2292 l = read(notify, inotify_buffer, sizeof(inotify_buffer));
2295 if (errno == EINTR || errno == EAGAIN)
2302 e = (struct inotify_event*) inotify_buffer;
2307 if (e->wd != wd || !(e->mask & IN_CLOSE)) {
2312 step = sizeof(struct inotify_event) + e->len;
2313 assert(step <= (size_t) l);
2315 e = (struct inotify_event*) ((uint8_t*) e + step);
2322 /* We close the tty fd here since if the old session
2323 * ended our handle will be dead. It's important that
2324 * we do this after sleeping, so that we don't enter
2325 * an endless loop. */
2326 close_nointr_nofail(fd);
2330 close_nointr_nofail(notify);
2332 r = reset_terminal_fd(fd, true);
2334 log_warning("Failed to reset terminal: %s", strerror(-r));
2340 close_nointr_nofail(fd);
2343 close_nointr_nofail(notify);
2348 int release_terminal(void) {
2350 struct sigaction sa_old, sa_new;
2352 if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC)) < 0)
2355 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2356 * by our own TIOCNOTTY */
2359 sa_new.sa_handler = SIG_IGN;
2360 sa_new.sa_flags = SA_RESTART;
2361 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2363 if (ioctl(fd, TIOCNOTTY) < 0)
2366 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2368 close_nointr_nofail(fd);
2372 int sigaction_many(const struct sigaction *sa, ...) {
2377 while ((sig = va_arg(ap, int)) > 0)
2378 if (sigaction(sig, sa, NULL) < 0)
2385 int ignore_signals(int sig, ...) {
2386 struct sigaction sa;
2391 sa.sa_handler = SIG_IGN;
2392 sa.sa_flags = SA_RESTART;
2394 if (sigaction(sig, &sa, NULL) < 0)
2398 while ((sig = va_arg(ap, int)) > 0)
2399 if (sigaction(sig, &sa, NULL) < 0)
2406 int default_signals(int sig, ...) {
2407 struct sigaction sa;
2412 sa.sa_handler = SIG_DFL;
2413 sa.sa_flags = SA_RESTART;
2415 if (sigaction(sig, &sa, NULL) < 0)
2419 while ((sig = va_arg(ap, int)) > 0)
2420 if (sigaction(sig, &sa, NULL) < 0)
2427 int close_pipe(int p[]) {
2433 a = close_nointr(p[0]);
2438 b = close_nointr(p[1]);
2442 return a < 0 ? a : b;
2445 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2454 while (nbytes > 0) {
2457 if ((k = read(fd, p, nbytes)) <= 0) {
2459 if (k < 0 && errno == EINTR)
2462 if (k < 0 && errno == EAGAIN && do_poll) {
2463 struct pollfd pollfd;
2467 pollfd.events = POLLIN;
2469 if (poll(&pollfd, 1, -1) < 0) {
2473 return n > 0 ? n : -errno;
2476 if (pollfd.revents != POLLIN)
2477 return n > 0 ? n : -EIO;
2482 return n > 0 ? n : (k < 0 ? -errno : 0);
2493 ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2502 while (nbytes > 0) {
2505 k = write(fd, p, nbytes);
2508 if (k < 0 && errno == EINTR)
2511 if (k < 0 && errno == EAGAIN && do_poll) {
2512 struct pollfd pollfd;
2516 pollfd.events = POLLOUT;
2518 if (poll(&pollfd, 1, -1) < 0) {
2522 return n > 0 ? n : -errno;
2525 if (pollfd.revents != POLLOUT)
2526 return n > 0 ? n : -EIO;
2531 return n > 0 ? n : (k < 0 ? -errno : 0);
2542 int parse_bytes(const char *t, off_t *bytes) {
2543 static const struct {
2549 { "M", 1024ULL*1024ULL },
2550 { "G", 1024ULL*1024ULL*1024ULL },
2551 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2552 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2553 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2570 l = strtoll(p, &e, 10);
2581 e += strspn(e, WHITESPACE);
2583 for (i = 0; i < ELEMENTSOF(table); i++)
2584 if (startswith(e, table[i].suffix)) {
2585 r += (off_t) l * table[i].factor;
2586 p = e + strlen(table[i].suffix);
2590 if (i >= ELEMENTSOF(table))
2600 int make_stdio(int fd) {
2605 r = dup3(fd, STDIN_FILENO, 0);
2606 s = dup3(fd, STDOUT_FILENO, 0);
2607 t = dup3(fd, STDERR_FILENO, 0);
2610 close_nointr_nofail(fd);
2612 if (r < 0 || s < 0 || t < 0)
2615 /* We rely here that the new fd has O_CLOEXEC not set */
2620 int make_null_stdio(void) {
2623 null_fd = open("/dev/null", O_RDWR|O_NOCTTY);
2627 return make_stdio(null_fd);
2630 bool is_device_path(const char *path) {
2632 /* Returns true on paths that refer to a device, either in
2633 * sysfs or in /dev */
2636 path_startswith(path, "/dev/") ||
2637 path_startswith(path, "/sys/");
2640 int dir_is_empty(const char *path) {
2641 _cleanup_closedir_ DIR *d;
2650 union dirent_storage buf;
2652 r = readdir_r(d, &buf.de, &de);
2659 if (!ignore_file(de->d_name))
2664 unsigned long long random_ull(void) {
2665 _cleanup_close_ int fd;
2669 fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
2673 r = loop_read(fd, &ull, sizeof(ull), true);
2674 if (r != sizeof(ull))
2680 return random() * RAND_MAX + random();
2683 void rename_process(const char name[8]) {
2686 /* This is a like a poor man's setproctitle(). It changes the
2687 * comm field, argv[0], and also the glibc's internally used
2688 * name of the process. For the first one a limit of 16 chars
2689 * applies, to the second one usually one of 10 (i.e. length
2690 * of "/sbin/init"), to the third one one of 7 (i.e. length of
2691 * "systemd"). If you pass a longer string it will be
2694 prctl(PR_SET_NAME, name);
2696 if (program_invocation_name)
2697 strncpy(program_invocation_name, name, strlen(program_invocation_name));
2699 if (saved_argc > 0) {
2703 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
2705 for (i = 1; i < saved_argc; i++) {
2709 memset(saved_argv[i], 0, strlen(saved_argv[i]));
2714 void sigset_add_many(sigset_t *ss, ...) {
2721 while ((sig = va_arg(ap, int)) > 0)
2722 assert_se(sigaddset(ss, sig) == 0);
2726 char* gethostname_malloc(void) {
2729 assert_se(uname(&u) >= 0);
2731 if (!isempty(u.nodename) && !streq(u.nodename, "(none)"))
2732 return strdup(u.nodename);
2734 return strdup(u.sysname);
2737 bool hostname_is_set(void) {
2740 assert_se(uname(&u) >= 0);
2742 return !isempty(u.nodename) && !streq(u.nodename, "(none)");
2745 static char *lookup_uid(uid_t uid) {
2748 _cleanup_free_ char *buf = NULL;
2749 struct passwd pwbuf, *pw = NULL;
2751 /* Shortcut things to avoid NSS lookups */
2753 return strdup("root");
2755 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
2759 buf = malloc(bufsize);
2763 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
2764 return strdup(pw->pw_name);
2766 if (asprintf(&name, "%lu", (unsigned long) uid) < 0)
2772 char* getlogname_malloc(void) {
2776 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
2781 return lookup_uid(uid);
2784 char *getusername_malloc(void) {
2791 return lookup_uid(getuid());
2794 int getttyname_malloc(int fd, char **r) {
2795 char path[PATH_MAX], *c;
2800 k = ttyname_r(fd, path, sizeof(path));
2806 c = strdup(startswith(path, "/dev/") ? path + 5 : path);
2814 int getttyname_harder(int fd, char **r) {
2818 k = getttyname_malloc(fd, &s);
2822 if (streq(s, "tty")) {
2824 return get_ctty(0, NULL, r);
2831 int get_ctty_devnr(pid_t pid, dev_t *d) {
2833 char line[LINE_MAX], *p, *fn;
2834 unsigned long ttynr;
2837 if (asprintf(&fn, "/proc/%lu/stat", (unsigned long) (pid <= 0 ? getpid() : pid)) < 0)
2840 f = fopen(fn, "re");
2845 if (!fgets(line, sizeof(line), f)) {
2846 k = feof(f) ? -EIO : -errno;
2853 p = strrchr(line, ')');
2863 "%*d " /* session */
2868 if (major(ttynr) == 0 && minor(ttynr) == 0)
2875 int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
2877 char fn[PATH_MAX], *s, *b, *p;
2882 k = get_ctty_devnr(pid, &devnr);
2886 snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
2889 k = readlink_malloc(fn, &s);
2895 /* This is an ugly hack */
2896 if (major(devnr) == 136) {
2897 if (asprintf(&b, "pts/%lu", (unsigned long) minor(devnr)) < 0)
2907 /* Probably something like the ptys which have no
2908 * symlink in /dev/char. Let's return something
2909 * vaguely useful. */
2922 if (startswith(s, "/dev/"))
2924 else if (startswith(s, "../"))
2942 int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
2948 /* This returns the first error we run into, but nevertheless
2949 * tries to go on. This closes the passed fd. */
2953 close_nointr_nofail(fd);
2955 return errno == ENOENT ? 0 : -errno;
2960 union dirent_storage buf;
2961 bool is_dir, keep_around;
2965 r = readdir_r(d, &buf.de, &de);
2966 if (r != 0 && ret == 0) {
2974 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
2977 if (de->d_type == DT_UNKNOWN ||
2979 (de->d_type == DT_DIR && root_dev)) {
2980 if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
2981 if (ret == 0 && errno != ENOENT)
2986 is_dir = S_ISDIR(st.st_mode);
2989 (st.st_uid == 0 || st.st_uid == getuid()) &&
2990 (st.st_mode & S_ISVTX);
2992 is_dir = de->d_type == DT_DIR;
2993 keep_around = false;
2999 /* if root_dev is set, remove subdirectories only, if device is same as dir */
3000 if (root_dev && st.st_dev != root_dev->st_dev)
3003 subdir_fd = openat(fd, de->d_name,
3004 O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3005 if (subdir_fd < 0) {
3006 if (ret == 0 && errno != ENOENT)
3011 r = rm_rf_children_dangerous(subdir_fd, only_dirs, honour_sticky, root_dev);
3012 if (r < 0 && ret == 0)
3016 if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
3017 if (ret == 0 && errno != ENOENT)
3021 } else if (!only_dirs && !keep_around) {
3023 if (unlinkat(fd, de->d_name, 0) < 0) {
3024 if (ret == 0 && errno != ENOENT)
3035 static int is_temporary_fs(struct statfs *s) {
3037 return s->f_type == TMPFS_MAGIC ||
3038 (long)s->f_type == (long)RAMFS_MAGIC;
3041 int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
3046 if (fstatfs(fd, &s) < 0) {
3047 close_nointr_nofail(fd);
3051 /* We refuse to clean disk file systems with this call. This
3052 * is extra paranoia just to be sure we never ever remove
3054 if (!is_temporary_fs(&s)) {
3055 log_error("Attempted to remove disk file system, and we can't allow that.");
3056 close_nointr_nofail(fd);
3060 return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev);
3063 static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
3069 /* We refuse to clean the root file system with this
3070 * call. This is extra paranoia to never cause a really
3071 * seriously broken system. */
3072 if (path_equal(path, "/")) {
3073 log_error("Attempted to remove entire root file system, and we can't allow that.");
3077 fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3080 if (errno != ENOTDIR)
3084 if (statfs(path, &s) < 0)
3087 if (!is_temporary_fs(&s)) {
3088 log_error("Attempted to remove disk file system, and we can't allow that.");
3093 if (delete_root && !only_dirs)
3094 if (unlink(path) < 0 && errno != ENOENT)
3101 if (fstatfs(fd, &s) < 0) {
3102 close_nointr_nofail(fd);
3106 if (!is_temporary_fs(&s)) {
3107 log_error("Attempted to remove disk file system, and we can't allow that.");
3108 close_nointr_nofail(fd);
3113 r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL);
3116 if (honour_sticky && file_is_priv_sticky(path) > 0)
3119 if (rmdir(path) < 0 && errno != ENOENT) {
3128 int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3129 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false);
3132 int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3133 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, true);
3136 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
3139 /* Under the assumption that we are running privileged we
3140 * first change the access mode and only then hand out
3141 * ownership to avoid a window where access is too open. */
3143 if (mode != (mode_t) -1)
3144 if (chmod(path, mode) < 0)
3147 if (uid != (uid_t) -1 || gid != (gid_t) -1)
3148 if (chown(path, uid, gid) < 0)
3154 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
3157 /* Under the assumption that we are running privileged we
3158 * first change the access mode and only then hand out
3159 * ownership to avoid a window where access is too open. */
3161 if (fchmod(fd, mode) < 0)
3164 if (fchown(fd, uid, gid) < 0)
3170 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
3174 /* Allocates the cpuset in the right size */
3177 if (!(r = CPU_ALLOC(n)))
3180 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
3181 CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
3191 if (errno != EINVAL)
3198 int status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) {
3199 static const char status_indent[] = " "; /* "[" STATUS "] " */
3200 _cleanup_free_ char *s = NULL;
3201 _cleanup_close_ int fd = -1;
3202 struct iovec iovec[5];
3207 /* This is independent of logging, as status messages are
3208 * optional and go exclusively to the console. */
3210 if (vasprintf(&s, format, ap) < 0)
3213 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
3226 sl = status ? sizeof(status_indent)-1 : 0;
3232 e = ellipsize(s, emax, 75);
3242 if (!isempty(status)) {
3243 IOVEC_SET_STRING(iovec[n++], "[");
3244 IOVEC_SET_STRING(iovec[n++], status);
3245 IOVEC_SET_STRING(iovec[n++], "] ");
3247 IOVEC_SET_STRING(iovec[n++], status_indent);
3250 IOVEC_SET_STRING(iovec[n++], s);
3251 IOVEC_SET_STRING(iovec[n++], "\n");
3253 if (writev(fd, iovec, n) < 0)
3259 int status_printf(const char *status, bool ellipse, const char *format, ...) {
3265 va_start(ap, format);
3266 r = status_vprintf(status, ellipse, format, ap);
3272 int status_welcome(void) {
3274 _cleanup_free_ char *pretty_name = NULL, *ansi_color = NULL;
3276 r = parse_env_file("/etc/os-release", NEWLINE,
3277 "PRETTY_NAME", &pretty_name,
3278 "ANSI_COLOR", &ansi_color,
3280 if (r < 0 && r != -ENOENT)
3281 log_warning("Failed to read /etc/os-release: %s", strerror(-r));
3283 return status_printf(NULL, false,
3284 "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
3285 isempty(ansi_color) ? "1" : ansi_color,
3286 isempty(pretty_name) ? "Linux" : pretty_name);
3289 char *replace_env(const char *format, char **env) {
3296 const char *e, *word = format;
3301 for (e = format; *e; e ++) {
3312 if (!(k = strnappend(r, word, e-word-1)))
3321 } else if (*e == '$') {
3322 if (!(k = strnappend(r, word, e-word)))
3338 if (!(t = strv_env_get_with_length(env, word+2, e-word-2)))
3341 if (!(k = strappend(r, t)))
3354 if (!(k = strnappend(r, word, e-word)))
3365 char **replace_env_argv(char **argv, char **env) {
3367 unsigned k = 0, l = 0;
3369 l = strv_length(argv);
3371 if (!(r = new(char*, l+1)))
3374 STRV_FOREACH(i, argv) {
3376 /* If $FOO appears as single word, replace it by the split up variable */
3377 if ((*i)[0] == '$' && (*i)[1] != '{') {
3382 if ((e = strv_env_get(env, *i+1))) {
3384 if (!(m = strv_split_quoted(e))) {
3395 if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
3404 memcpy(r + k, m, q * sizeof(char*));
3412 /* If ${FOO} appears as part of a word, replace it by the variable as-is */
3413 if (!(r[k++] = replace_env(*i, env))) {
3423 int fd_columns(int fd) {
3427 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3436 unsigned columns(void) {
3440 if (_likely_(cached_columns > 0))
3441 return cached_columns;
3444 e = getenv("COLUMNS");
3449 c = fd_columns(STDOUT_FILENO);
3458 int fd_lines(int fd) {
3462 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3471 unsigned lines(void) {
3475 if (_likely_(cached_lines > 0))
3476 return cached_lines;
3479 e = getenv("LINES");
3484 l = fd_lines(STDOUT_FILENO);
3490 return cached_lines;
3493 /* intended to be used as a SIGWINCH sighandler */
3494 void columns_lines_cache_reset(int signum) {
3500 static int cached_on_tty = -1;
3502 if (_unlikely_(cached_on_tty < 0))
3503 cached_on_tty = isatty(STDOUT_FILENO) > 0;
3505 return cached_on_tty;
3508 int running_in_chroot(void) {
3514 /* Only works as root */
3516 if (stat("/proc/1/root", &a) < 0)
3519 if (stat("/", &b) < 0)
3523 a.st_dev != b.st_dev ||
3524 a.st_ino != b.st_ino;
3527 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
3532 assert(percent <= 100);
3533 assert(new_length >= 3);
3535 if (old_length <= 3 || old_length <= new_length)
3536 return strndup(s, old_length);
3538 r = new0(char, new_length+1);
3542 x = (new_length * percent) / 100;
3544 if (x > new_length - 3)
3552 s + old_length - (new_length - x - 3),
3553 new_length - x - 3);
3558 char *ellipsize(const char *s, size_t length, unsigned percent) {
3559 return ellipsize_mem(s, strlen(s), length, percent);
3562 int touch(const char *path) {
3567 /* This just opens the file for writing, ensuring it
3568 * exists. It doesn't call utimensat() the way /usr/bin/touch
3571 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644);
3575 close_nointr_nofail(fd);
3579 char *unquote(const char *s, const char* quotes) {
3583 /* This is rather stupid, simply removes the heading and
3584 * trailing quotes if there is one. Doesn't care about
3585 * escaping or anything. We should make this smarter one
3592 if (strchr(quotes, s[0]) && s[l-1] == s[0])
3593 return strndup(s+1, l-2);
3598 char *normalize_env_assignment(const char *s) {
3599 _cleanup_free_ char *name = NULL, *value = NULL, *p = NULL;
3602 eq = strchr(s, '=');
3614 memmove(r, t, strlen(t) + 1);
3618 name = strndup(s, eq - s);
3626 value = unquote(strstrip(p), QUOTES);
3630 if (asprintf(&r, "%s=%s", strstrip(name), value) < 0)
3636 int wait_for_terminate(pid_t pid, siginfo_t *status) {
3647 if (waitid(P_PID, pid, status, WEXITED) < 0) {
3659 int wait_for_terminate_and_warn(const char *name, pid_t pid) {
3666 r = wait_for_terminate(pid, &status);
3668 log_warning("Failed to wait for %s: %s", name, strerror(-r));
3672 if (status.si_code == CLD_EXITED) {
3673 if (status.si_status != 0) {
3674 log_warning("%s failed with error code %i.", name, status.si_status);
3675 return status.si_status;
3678 log_debug("%s succeeded.", name);
3681 } else if (status.si_code == CLD_KILLED ||
3682 status.si_code == CLD_DUMPED) {
3684 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
3688 log_warning("%s failed due to unknown reason.", name);
3692 _noreturn_ void freeze(void) {
3694 /* Make sure nobody waits for us on a socket anymore */
3695 close_all_fds(NULL, 0);
3703 bool null_or_empty(struct stat *st) {
3706 if (S_ISREG(st->st_mode) && st->st_size <= 0)
3709 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
3715 int null_or_empty_path(const char *fn) {
3720 if (stat(fn, &st) < 0)
3723 return null_or_empty(&st);
3726 DIR *xopendirat(int fd, const char *name, int flags) {
3730 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags);
3736 close_nointr_nofail(nfd);
3743 int signal_from_string_try_harder(const char *s) {
3747 signo = signal_from_string(s);
3749 if (startswith(s, "SIG"))
3750 return signal_from_string(s+3);
3755 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
3759 /* FIXME: to follow udev's logic 100% we need to leave valid
3760 * UTF8 chars unescaped */
3762 u = unquote(tagvalue, "\"\'");
3766 t = xescape(u, "/ ");
3772 r = asprintf(&dn, "/dev/disk/by-%s/%s", by, t);
3781 char *fstab_node_to_udev_node(const char *p) {
3784 if (startswith(p, "LABEL="))
3785 return tag_to_udev_node(p+6, "label");
3787 if (startswith(p, "UUID="))
3788 return tag_to_udev_node(p+5, "uuid");
3790 if (startswith(p, "PARTUUID="))
3791 return tag_to_udev_node(p+9, "partuuid");
3793 if (startswith(p, "PARTLABEL="))
3794 return tag_to_udev_node(p+10, "partlabel");
3799 bool tty_is_vc(const char *tty) {
3802 if (startswith(tty, "/dev/"))
3805 return vtnr_from_tty(tty) >= 0;
3808 bool tty_is_console(const char *tty) {
3811 if (startswith(tty, "/dev/"))
3814 return streq(tty, "console");
3817 int vtnr_from_tty(const char *tty) {
3822 if (startswith(tty, "/dev/"))
3825 if (!startswith(tty, "tty") )
3828 if (tty[3] < '0' || tty[3] > '9')
3831 r = safe_atoi(tty+3, &i);
3835 if (i < 0 || i > 63)
3841 bool tty_is_vc_resolve(const char *tty) {
3842 char *active = NULL;
3847 if (startswith(tty, "/dev/"))
3850 /* Resolve where /dev/console is pointing to, if /sys is
3851 * actually ours (i.e. not read-only-mounted which is a sign
3852 * for container setups) */
3853 if (streq(tty, "console") && path_is_read_only_fs("/sys") <= 0)
3854 if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) {
3855 /* If multiple log outputs are configured the
3856 * last one is what /dev/console points to */
3857 tty = strrchr(active, ' ');
3870 const char *default_term_for_tty(const char *tty) {
3873 return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102";
3876 bool dirent_is_file(const struct dirent *de) {
3879 if (ignore_file(de->d_name))
3882 if (de->d_type != DT_REG &&
3883 de->d_type != DT_LNK &&
3884 de->d_type != DT_UNKNOWN)
3890 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
3893 if (de->d_type != DT_REG &&
3894 de->d_type != DT_LNK &&
3895 de->d_type != DT_UNKNOWN)
3898 if (ignore_file_allow_backup(de->d_name))
3901 return endswith(de->d_name, suffix);
3904 void execute_directory(const char *directory, DIR *d, char *argv[]) {
3907 Hashmap *pids = NULL;
3911 /* Executes all binaries in a directory in parallel and waits
3912 * until all they all finished. */
3915 if (!(_d = opendir(directory))) {
3917 if (errno == ENOENT)
3920 log_error("Failed to enumerate directory %s: %m", directory);
3927 if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) {
3928 log_error("Failed to allocate set.");
3932 while ((de = readdir(d))) {
3937 if (!dirent_is_file(de))
3940 if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
3945 if ((pid = fork()) < 0) {
3946 log_error("Failed to fork: %m");
3964 log_error("Failed to execute %s: %m", path);
3965 _exit(EXIT_FAILURE);
3968 log_debug("Spawned %s as %lu", path, (unsigned long) pid);
3970 if ((k = hashmap_put(pids, UINT_TO_PTR(pid), path)) < 0) {
3971 log_error("Failed to add PID to set: %s", strerror(-k));
3976 while (!hashmap_isempty(pids)) {
3977 pid_t pid = PTR_TO_UINT(hashmap_first_key(pids));
3982 if (waitid(P_PID, pid, &si, WEXITED) < 0) {
3987 log_error("waitid() failed: %m");
3991 if ((path = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) {
3992 if (!is_clean_exit(si.si_code, si.si_status, NULL)) {
3993 if (si.si_code == CLD_EXITED)
3994 log_error("%s exited with exit status %i.", path, si.si_status);
3996 log_error("%s terminated by signal %s.", path, signal_to_string(si.si_status));
3998 log_debug("%s exited successfully.", path);
4009 hashmap_free_free(pids);
4012 int kill_and_sigcont(pid_t pid, int sig) {
4015 r = kill(pid, sig) < 0 ? -errno : 0;
4023 bool nulstr_contains(const char*nulstr, const char *needle) {
4029 NULSTR_FOREACH(i, nulstr)
4030 if (streq(i, needle))
4036 bool plymouth_running(void) {
4037 return access("/run/plymouth/pid", F_OK) >= 0;
4040 char* strshorten(char *s, size_t l) {
4049 static bool hostname_valid_char(char c) {
4051 (c >= 'a' && c <= 'z') ||
4052 (c >= 'A' && c <= 'Z') ||
4053 (c >= '0' && c <= '9') ||
4059 bool hostname_is_valid(const char *s) {
4065 for (p = s; *p; p++)
4066 if (!hostname_valid_char(*p))
4069 if (p-s > HOST_NAME_MAX)
4075 char* hostname_cleanup(char *s) {
4078 for (p = s, d = s; *p; p++)
4079 if ((*p >= 'a' && *p <= 'z') ||
4080 (*p >= 'A' && *p <= 'Z') ||
4081 (*p >= '0' && *p <= '9') ||
4089 strshorten(s, HOST_NAME_MAX);
4093 int pipe_eof(int fd) {
4094 struct pollfd pollfd;
4099 pollfd.events = POLLIN|POLLHUP;
4101 r = poll(&pollfd, 1, 0);
4108 return pollfd.revents & POLLHUP;
4111 int fd_wait_for_event(int fd, int event, usec_t t) {
4112 struct pollfd pollfd;
4117 pollfd.events = event;
4119 r = poll(&pollfd, 1, t == (usec_t) -1 ? -1 : (int) (t / USEC_PER_MSEC));
4126 return pollfd.revents;
4129 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
4140 t = new(char, strlen(path) + 1 + 6 + 1);
4144 fn = path_get_file_name(path);
4148 stpcpy(stpcpy(t+k+1, fn), "XXXXXX");
4150 fd = mkostemp(t, O_WRONLY|O_CLOEXEC);
4156 f = fdopen(fd, "we");
4169 int terminal_vhangup_fd(int fd) {
4172 if (ioctl(fd, TIOCVHANGUP) < 0)
4178 int terminal_vhangup(const char *name) {
4181 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4185 r = terminal_vhangup_fd(fd);
4186 close_nointr_nofail(fd);
4191 int vt_disallocate(const char *name) {
4195 /* Deallocate the VT if possible. If not possible
4196 * (i.e. because it is the active one), at least clear it
4197 * entirely (including the scrollback buffer) */
4199 if (!startswith(name, "/dev/"))
4202 if (!tty_is_vc(name)) {
4203 /* So this is not a VT. I guess we cannot deallocate
4204 * it then. But let's at least clear the screen */
4206 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4211 "\033[r" /* clear scrolling region */
4212 "\033[H" /* move home */
4213 "\033[2J", /* clear screen */
4215 close_nointr_nofail(fd);
4220 if (!startswith(name, "/dev/tty"))
4223 r = safe_atou(name+8, &u);
4230 /* Try to deallocate */
4231 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
4235 r = ioctl(fd, VT_DISALLOCATE, u);
4236 close_nointr_nofail(fd);
4244 /* Couldn't deallocate, so let's clear it fully with
4246 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4251 "\033[r" /* clear scrolling region */
4252 "\033[H" /* move home */
4253 "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
4255 close_nointr_nofail(fd);
4260 int copy_file(const char *from, const char *to) {
4266 fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
4270 fdt = open(to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY, 0644);
4272 close_nointr_nofail(fdf);
4280 n = read(fdf, buf, sizeof(buf));
4284 close_nointr_nofail(fdf);
4295 k = loop_write(fdt, buf, n, false);
4297 r = k < 0 ? k : (errno ? -errno : -EIO);
4299 close_nointr_nofail(fdf);
4307 close_nointr_nofail(fdf);
4308 r = close_nointr(fdt);
4318 int symlink_atomic(const char *from, const char *to) {
4320 _cleanup_free_ char *t;
4323 unsigned long long ull;
4330 t = new(char, strlen(to) + 1 + 16 + 1);
4334 fn = path_get_file_name(to);
4338 x = stpcpy(t+k+1, fn);
4341 for (i = 0; i < 16; i++) {
4342 *(x++) = hexchar(ull & 0xF);
4348 if (symlink(from, t) < 0)
4351 if (rename(t, to) < 0) {
4360 bool display_is_local(const char *display) {
4364 display[0] == ':' &&
4365 display[1] >= '0' &&
4369 int socket_from_display(const char *display, char **path) {
4376 if (!display_is_local(display))
4379 k = strspn(display+1, "0123456789");
4381 f = new(char, sizeof("/tmp/.X11-unix/X") + k);
4385 c = stpcpy(f, "/tmp/.X11-unix/X");
4386 memcpy(c, display+1, k);
4395 const char **username,
4396 uid_t *uid, gid_t *gid,
4398 const char **shell) {
4406 /* We enforce some special rules for uid=0: in order to avoid
4407 * NSS lookups for root we hardcode its data. */
4409 if (streq(*username, "root") || streq(*username, "0")) {
4427 if (parse_uid(*username, &u) >= 0) {
4431 /* If there are multiple users with the same id, make
4432 * sure to leave $USER to the configured value instead
4433 * of the first occurrence in the database. However if
4434 * the uid was configured by a numeric uid, then let's
4435 * pick the real username from /etc/passwd. */
4437 *username = p->pw_name;
4440 p = getpwnam(*username);
4444 return errno != 0 ? -errno : -ESRCH;
4456 *shell = p->pw_shell;
4461 char* uid_to_name(uid_t uid) {
4466 return strdup("root");
4470 return strdup(p->pw_name);
4472 if (asprintf(&r, "%lu", (unsigned long) uid) < 0)
4478 int get_group_creds(const char **groupname, gid_t *gid) {
4484 /* We enforce some special rules for gid=0: in order to avoid
4485 * NSS lookups for root we hardcode its data. */
4487 if (streq(*groupname, "root") || streq(*groupname, "0")) {
4488 *groupname = "root";
4496 if (parse_gid(*groupname, &id) >= 0) {
4501 *groupname = g->gr_name;
4504 g = getgrnam(*groupname);
4508 return errno != 0 ? -errno : -ESRCH;
4516 int in_group(const char *name) {
4518 int ngroups_max, r, i;
4520 r = get_group_creds(&name, &gid);
4524 if (getgid() == gid)
4527 if (getegid() == gid)
4530 ngroups_max = sysconf(_SC_NGROUPS_MAX);
4531 assert(ngroups_max > 0);
4533 gids = alloca(sizeof(gid_t) * ngroups_max);
4535 r = getgroups(ngroups_max, gids);
4539 for (i = 0; i < r; i++)
4546 int glob_exists(const char *path) {
4554 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
4556 if (k == GLOB_NOMATCH)
4558 else if (k == GLOB_NOSPACE)
4561 r = !strv_isempty(g.gl_pathv);
4563 r = errno ? -errno : -EIO;
4570 int dirent_ensure_type(DIR *d, struct dirent *de) {
4576 if (de->d_type != DT_UNKNOWN)
4579 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
4583 S_ISREG(st.st_mode) ? DT_REG :
4584 S_ISDIR(st.st_mode) ? DT_DIR :
4585 S_ISLNK(st.st_mode) ? DT_LNK :
4586 S_ISFIFO(st.st_mode) ? DT_FIFO :
4587 S_ISSOCK(st.st_mode) ? DT_SOCK :
4588 S_ISCHR(st.st_mode) ? DT_CHR :
4589 S_ISBLK(st.st_mode) ? DT_BLK :
4595 int in_search_path(const char *path, char **search) {
4599 r = path_get_parent(path, &parent);
4605 STRV_FOREACH(i, search) {
4606 if (path_equal(parent, *i)) {
4617 int get_files_in_directory(const char *path, char ***list) {
4625 /* Returns all files in a directory in *list, and the number
4626 * of files as return value. If list is NULL returns only the
4635 union dirent_storage buf;
4638 k = readdir_r(d, &buf.de, &de);
4647 dirent_ensure_type(d, de);
4649 if (!dirent_is_file(de))
4653 if ((unsigned) r >= n) {
4657 t = realloc(l, sizeof(char*) * n);
4666 assert((unsigned) r < n);
4668 l[r] = strdup(de->d_name);
4692 char *strjoin(const char *x, ...) {
4706 t = va_arg(ap, const char *);
4711 if (n > ((size_t) -1) - l) {
4735 t = va_arg(ap, const char *);
4749 bool is_main_thread(void) {
4750 static __thread int cached = 0;
4752 if (_unlikely_(cached == 0))
4753 cached = getpid() == gettid() ? 1 : -1;
4758 int block_get_whole_disk(dev_t d, dev_t *ret) {
4765 /* If it has a queue this is good enough for us */
4766 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
4769 r = access(p, F_OK);
4777 /* If it is a partition find the originating device */
4778 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
4781 r = access(p, F_OK);
4787 /* Get parent dev_t */
4788 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
4791 r = read_one_line_file(p, &s);
4797 r = sscanf(s, "%u:%u", &m, &n);
4803 /* Only return this if it is really good enough for us. */
4804 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
4807 r = access(p, F_OK);
4811 *ret = makedev(m, n);
4818 int file_is_priv_sticky(const char *p) {
4823 if (lstat(p, &st) < 0)
4827 (st.st_uid == 0 || st.st_uid == getuid()) &&
4828 (st.st_mode & S_ISVTX);
4831 static const char *const ioprio_class_table[] = {
4832 [IOPRIO_CLASS_NONE] = "none",
4833 [IOPRIO_CLASS_RT] = "realtime",
4834 [IOPRIO_CLASS_BE] = "best-effort",
4835 [IOPRIO_CLASS_IDLE] = "idle"
4838 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
4840 static const char *const sigchld_code_table[] = {
4841 [CLD_EXITED] = "exited",
4842 [CLD_KILLED] = "killed",
4843 [CLD_DUMPED] = "dumped",
4844 [CLD_TRAPPED] = "trapped",
4845 [CLD_STOPPED] = "stopped",
4846 [CLD_CONTINUED] = "continued",
4849 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
4851 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
4852 [LOG_FAC(LOG_KERN)] = "kern",
4853 [LOG_FAC(LOG_USER)] = "user",
4854 [LOG_FAC(LOG_MAIL)] = "mail",
4855 [LOG_FAC(LOG_DAEMON)] = "daemon",
4856 [LOG_FAC(LOG_AUTH)] = "auth",
4857 [LOG_FAC(LOG_SYSLOG)] = "syslog",
4858 [LOG_FAC(LOG_LPR)] = "lpr",
4859 [LOG_FAC(LOG_NEWS)] = "news",
4860 [LOG_FAC(LOG_UUCP)] = "uucp",
4861 [LOG_FAC(LOG_CRON)] = "cron",
4862 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
4863 [LOG_FAC(LOG_FTP)] = "ftp",
4864 [LOG_FAC(LOG_LOCAL0)] = "local0",
4865 [LOG_FAC(LOG_LOCAL1)] = "local1",
4866 [LOG_FAC(LOG_LOCAL2)] = "local2",
4867 [LOG_FAC(LOG_LOCAL3)] = "local3",
4868 [LOG_FAC(LOG_LOCAL4)] = "local4",
4869 [LOG_FAC(LOG_LOCAL5)] = "local5",
4870 [LOG_FAC(LOG_LOCAL6)] = "local6",
4871 [LOG_FAC(LOG_LOCAL7)] = "local7"
4874 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
4876 static const char *const log_level_table[] = {
4877 [LOG_EMERG] = "emerg",
4878 [LOG_ALERT] = "alert",
4879 [LOG_CRIT] = "crit",
4881 [LOG_WARNING] = "warning",
4882 [LOG_NOTICE] = "notice",
4883 [LOG_INFO] = "info",
4884 [LOG_DEBUG] = "debug"
4887 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
4889 static const char* const sched_policy_table[] = {
4890 [SCHED_OTHER] = "other",
4891 [SCHED_BATCH] = "batch",
4892 [SCHED_IDLE] = "idle",
4893 [SCHED_FIFO] = "fifo",
4897 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
4899 static const char* const rlimit_table[] = {
4900 [RLIMIT_CPU] = "LimitCPU",
4901 [RLIMIT_FSIZE] = "LimitFSIZE",
4902 [RLIMIT_DATA] = "LimitDATA",
4903 [RLIMIT_STACK] = "LimitSTACK",
4904 [RLIMIT_CORE] = "LimitCORE",
4905 [RLIMIT_RSS] = "LimitRSS",
4906 [RLIMIT_NOFILE] = "LimitNOFILE",
4907 [RLIMIT_AS] = "LimitAS",
4908 [RLIMIT_NPROC] = "LimitNPROC",
4909 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
4910 [RLIMIT_LOCKS] = "LimitLOCKS",
4911 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
4912 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
4913 [RLIMIT_NICE] = "LimitNICE",
4914 [RLIMIT_RTPRIO] = "LimitRTPRIO",
4915 [RLIMIT_RTTIME] = "LimitRTTIME"
4918 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
4920 static const char* const ip_tos_table[] = {
4921 [IPTOS_LOWDELAY] = "low-delay",
4922 [IPTOS_THROUGHPUT] = "throughput",
4923 [IPTOS_RELIABILITY] = "reliability",
4924 [IPTOS_LOWCOST] = "low-cost",
4927 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
4929 static const char *const __signal_table[] = {
4946 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
4957 [SIGVTALRM] = "VTALRM",
4959 [SIGWINCH] = "WINCH",
4965 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
4967 const char *signal_to_string(int signo) {
4968 static __thread char buf[12];
4971 name = __signal_to_string(signo);
4975 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
4976 snprintf(buf, sizeof(buf) - 1, "RTMIN+%d", signo - SIGRTMIN);
4978 snprintf(buf, sizeof(buf) - 1, "%d", signo);
4983 int signal_from_string(const char *s) {
4988 signo = __signal_from_string(s);
4992 if (startswith(s, "RTMIN+")) {
4996 if (safe_atou(s, &u) >= 0) {
4997 signo = (int) u + offset;
4998 if (signo > 0 && signo < _NSIG)
5004 bool kexec_loaded(void) {
5005 bool loaded = false;
5008 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
5016 int strdup_or_null(const char *a, char **b) {
5034 int prot_from_flags(int flags) {
5036 switch (flags & O_ACCMODE) {
5045 return PROT_READ|PROT_WRITE;
5052 char *format_bytes(char *buf, size_t l, off_t t) {
5055 static const struct {
5059 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5060 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5061 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
5062 { "G", 1024ULL*1024ULL*1024ULL },
5063 { "M", 1024ULL*1024ULL },
5067 for (i = 0; i < ELEMENTSOF(table); i++) {
5069 if (t >= table[i].factor) {
5072 (unsigned long long) (t / table[i].factor),
5073 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
5080 snprintf(buf, l, "%lluB", (unsigned long long) t);
5088 void* memdup(const void *p, size_t l) {
5101 int fd_inc_sndbuf(int fd, size_t n) {
5103 socklen_t l = sizeof(value);
5105 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
5107 l == sizeof(value) &&
5108 (size_t) value >= n*2)
5112 r = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value));
5119 int fd_inc_rcvbuf(int fd, size_t n) {
5121 socklen_t l = sizeof(value);
5123 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
5125 l == sizeof(value) &&
5126 (size_t) value >= n*2)
5130 r = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value));
5137 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
5138 pid_t parent_pid, agent_pid;
5140 bool stdout_is_tty, stderr_is_tty;
5148 parent_pid = getpid();
5150 /* Spawns a temporary TTY agent, making sure it goes away when
5157 if (agent_pid != 0) {
5164 * Make sure the agent goes away when the parent dies */
5165 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
5166 _exit(EXIT_FAILURE);
5168 /* Check whether our parent died before we were able
5169 * to set the death signal */
5170 if (getppid() != parent_pid)
5171 _exit(EXIT_SUCCESS);
5173 /* Don't leak fds to the agent */
5174 close_all_fds(except, n_except);
5176 stdout_is_tty = isatty(STDOUT_FILENO);
5177 stderr_is_tty = isatty(STDERR_FILENO);
5179 if (!stdout_is_tty || !stderr_is_tty) {
5180 /* Detach from stdout/stderr. and reopen
5181 * /dev/tty for them. This is important to
5182 * ensure that when systemctl is started via
5183 * popen() or a similar call that expects to
5184 * read EOF we actually do generate EOF and
5185 * not delay this indefinitely by because we
5186 * keep an unused copy of stdin around. */
5187 fd = open("/dev/tty", O_WRONLY);
5189 log_error("Failed to open /dev/tty: %m");
5190 _exit(EXIT_FAILURE);
5194 dup2(fd, STDOUT_FILENO);
5197 dup2(fd, STDERR_FILENO);
5203 /* Count arguments */
5205 for (n = 0; va_arg(ap, char*); n++)
5210 l = alloca(sizeof(char *) * (n + 1));
5212 /* Fill in arguments */
5214 for (i = 0; i <= n; i++)
5215 l[i] = va_arg(ap, char*);
5219 _exit(EXIT_FAILURE);
5222 int setrlimit_closest(int resource, const struct rlimit *rlim) {
5223 struct rlimit highest, fixed;
5227 if (setrlimit(resource, rlim) >= 0)
5233 /* So we failed to set the desired setrlimit, then let's try
5234 * to get as close as we can */
5235 assert_se(getrlimit(resource, &highest) == 0);
5237 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
5238 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
5240 if (setrlimit(resource, &fixed) < 0)
5246 int getenv_for_pid(pid_t pid, const char *field, char **_value) {
5247 char path[sizeof("/proc/")-1+10+sizeof("/environ")], *value = NULL;
5259 snprintf(path, sizeof(path), "/proc/%lu/environ", (unsigned long) pid);
5262 f = fopen(path, "re");
5270 char line[LINE_MAX];
5273 for (i = 0; i < sizeof(line)-1; i++) {
5277 if (_unlikely_(c == EOF)) {
5287 if (memcmp(line, field, l) == 0 && line[l] == '=') {
5288 value = strdup(line + l + 1);
5308 int can_sleep(const char *type) {
5312 _cleanup_free_ char *p = NULL;
5316 /* If /sys is read-only we cannot sleep */
5317 if (access("/sys/power/state", W_OK) < 0)
5320 r = read_one_line_file("/sys/power/state", &p);
5325 FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state)
5326 if (l == k && memcmp(w, type, l) == 0)
5332 int can_sleep_disk(const char *type) {
5336 _cleanup_free_ char *p = NULL;
5340 /* If /sys is read-only we cannot sleep */
5341 if (access("/sys/power/state", W_OK) < 0 ||
5342 access("/sys/power/disk", W_OK) < 0)
5345 r = read_one_line_file("/sys/power/disk", &p);
5350 FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state) {
5351 if (l == k && memcmp(w, type, l) == 0)
5354 if (l == k + 2 && w[0] == '[' && memcmp(w + 1, type, l - 2) == 0 && w[l-1] == ']')
5361 bool is_valid_documentation_url(const char *url) {
5364 if (startswith(url, "http://") && url[7])
5367 if (startswith(url, "https://") && url[8])
5370 if (startswith(url, "file:") && url[5])
5373 if (startswith(url, "info:") && url[5])
5376 if (startswith(url, "man:") && url[4])
5382 bool in_initrd(void) {
5383 static __thread int saved = -1;
5389 /* We make two checks here:
5391 * 1. the flag file /etc/initrd-release must exist
5392 * 2. the root file system must be a memory file system
5394 * The second check is extra paranoia, since misdetecting an
5395 * initrd can have bad bad consequences due the initrd
5396 * emptying when transititioning to the main systemd.
5399 saved = access("/etc/initrd-release", F_OK) >= 0 &&
5400 statfs("/", &s) >= 0 &&
5401 is_temporary_fs(&s);
5406 void warn_melody(void) {
5407 _cleanup_close_ int fd = -1;
5409 fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
5413 /* Yeah, this is synchronous. Kinda sucks. But well... */
5415 ioctl(fd, KIOCSOUND, (int)(1193180/440));
5416 usleep(125*USEC_PER_MSEC);
5418 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5419 usleep(125*USEC_PER_MSEC);
5421 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5422 usleep(125*USEC_PER_MSEC);
5424 ioctl(fd, KIOCSOUND, 0);
5427 int make_console_stdio(void) {
5430 /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
5432 fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1);
5434 log_error("Failed to acquire terminal: %s", strerror(-fd));
5440 log_error("Failed to duplicate terminal fd: %s", strerror(-r));
5447 int get_home_dir(char **_h) {
5455 /* Take the user specified one */
5466 /* Hardcode home directory for root to avoid NSS */
5469 h = strdup("/root");
5477 /* Check the database... */
5481 return errno ? -errno : -ESRCH;
5483 if (!path_is_absolute(p->pw_dir))
5486 h = strdup(p->pw_dir);
5494 int get_shell(char **_sh) {
5502 /* Take the user specified one */
5503 e = getenv("SHELL");
5513 /* Hardcode home directory for root to avoid NSS */
5516 sh = strdup("/bin/sh");
5524 /* Check the database... */
5528 return errno ? -errno : -ESRCH;
5530 if (!path_is_absolute(p->pw_shell))
5533 sh = strdup(p->pw_shell);
5541 void freep(void *p) {
5545 void fclosep(FILE **f) {
5550 void closep(int *fd) {
5552 close_nointr_nofail(*fd);
5555 void closedirp(DIR **d) {
5560 void umaskp(mode_t *u) {
5564 bool filename_is_safe(const char *p) {
5578 if (strlen(p) > FILENAME_MAX)
5584 bool string_is_safe(const char *p) {
5589 for (t = p; *t; t++) {
5590 if (*t > 0 && *t < ' ')
5593 if (strchr("\\\"\'", *t))
5600 /* hey glibc, APIs with callbacks without a user pointer are so useless */
5601 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
5602 int (*compar) (const void *, const void *, void *), void *arg) {
5611 p = (void *)(((const char *) base) + (idx * size));
5612 comparison = compar(key, p, arg);
5615 else if (comparison > 0)
5623 bool is_locale_utf8(void) {
5625 static int cached_answer = -1;
5627 if (cached_answer >= 0)
5630 if (!setlocale(LC_ALL, "")) {
5631 cached_answer = true;
5635 set = nl_langinfo(CODESET);
5637 cached_answer = true;
5641 cached_answer = streq(set, "UTF-8");
5643 return (bool)cached_answer;
5646 const char *draw_special_char(DrawSpecialChar ch) {
5647 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
5649 [DRAW_TREE_VERT] = "\342\224\202 ", /* │ */
5650 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
5651 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
5652 [DRAW_TRIANGULAR_BULLET] = "\342\200\243 ", /* ‣ */
5654 /* ASCII fallback */ {
5655 [DRAW_TREE_VERT] = "| ",
5656 [DRAW_TREE_BRANCH] = "|-",
5657 [DRAW_TREE_RIGHT] = "`-",
5658 [DRAW_TRIANGULAR_BULLET] = "> ",
5662 return draw_table[!is_locale_utf8()][ch];
5665 char *strreplace(const char *text, const char *old_string, const char *new_string) {
5668 size_t l, old_len, new_len;
5674 old_len = strlen(old_string);
5675 new_len = strlen(new_string);
5688 if (!startswith(f, old_string)) {
5694 nl = l - old_len + new_len;
5695 a = realloc(r, nl + 1);
5703 t = stpcpy(t, new_string);
5715 char *strip_tab_ansi(char **ibuf, size_t *_isz) {
5716 const char *i, *begin = NULL;
5721 } state = STATE_OTHER;
5723 size_t osz = 0, isz;
5729 /* Strips ANSI color and replaces TABs by 8 spaces */
5731 isz = _isz ? *_isz : strlen(*ibuf);
5733 f = open_memstream(&obuf, &osz);
5737 for (i = *ibuf; i < *ibuf + isz + 1; i++) {
5742 if (i >= *ibuf + isz) /* EOT */
5744 else if (*i == '\x1B')
5745 state = STATE_ESCAPE;
5746 else if (*i == '\t')
5753 if (i >= *ibuf + isz) { /* EOT */
5756 } else if (*i == '[') {
5757 state = STATE_BRACKET;
5762 state = STATE_OTHER;
5769 if (i >= *ibuf + isz || /* EOT */
5770 (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
5773 state = STATE_OTHER;
5775 } else if (*i == 'm')
5776 state = STATE_OTHER;
5798 int on_ac_power(void) {
5799 bool found_offline = false, found_online = false;
5800 _cleanup_closedir_ DIR *d = NULL;
5802 d = opendir("/sys/class/power_supply");
5808 union dirent_storage buf;
5809 _cleanup_free_ char *p = NULL;
5810 _cleanup_close_ int fd = -1, device = -1;
5815 k = readdir_r(d, &buf.de, &de);
5822 if (ignore_file(de->d_name))
5825 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
5827 if (errno == ENOENT || errno == ENOTDIR)
5833 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
5835 if (errno == ENOENT)
5841 n = read(fd, contents, sizeof(contents));
5845 if (n != 6 || memcmp(contents, "Mains\n", 6))
5848 close_nointr_nofail(fd);
5849 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
5851 if (errno == ENOENT)
5857 n = read(fd, contents, sizeof(contents));
5861 if (n != 2 || contents[1] != '\n')
5864 if (contents[0] == '1') {
5865 found_online = true;
5867 } else if (contents[0] == '0')
5868 found_offline = true;
5873 return found_online || !found_offline;