util.c revision 6294aa76d818e831de4592b41a37e225fd0871f9
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek This file is part of systemd.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Copyright 2010 Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (at your option) any later version.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyerstatic volatile unsigned cached_columns = 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic volatile unsigned cached_lines = 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek static thread_local size_t pgsz = 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekbool streq_ptr(const char *a, const char *b) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Like streq(), but tries to make sense of NULL pointers */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekchar* endswith(const char *s, const char *postfix) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return (char*) s + sl;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekbool first_word(const char *s, const char *word) {
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek return s[wl] == 0 ||
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek * Just ignore EINTR; a retry loop is the wrong
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek * thing to do on Linux.
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
da2e288bbc4d8cebaa1d38a80f6eec8cde3e9cceLennart Poettering * https://bugzilla.gnome.org/show_bug.cgi?id=682819
da2e288bbc4d8cebaa1d38a80f6eec8cde3e9cceLennart Poettering * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
da2e288bbc4d8cebaa1d38a80f6eec8cde3e9cceLennart Poettering * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek * Like close_nointr() but cannot fail. Guarantees errno is
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * unchanged. Is a NOP with negative fds passed, and returns
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * -1, so that it can be used in this syntax:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * fd = safe_close(fd);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* The kernel might return pretty much any error code
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * via close(), but the fd will be closed anyway. The
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * only condition we want to check for here is whether
4608af4333d0f7f5f8e3bc632801b04ef07d246dLennart Poettering * the fd was invalid at all... */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekvoid close_many(const int fds[], unsigned n_fd) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek for (i = 0; i < n_fd; i++)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint unlink_noerrno(const char *path) {
23ad4dd8844c582929115a11ed2830a1371568d6Jan Alexander Steffens (heftig)int parse_boolean(const char *v) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || strcaseeq(v, "on"))
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || strcaseeq(v, "off"))
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint parse_pid(const char *s, pid_t* ret_pid) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek unsigned long ul = 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint parse_uid(const char *s, uid_t* ret_uid) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek unsigned long ul = 0;
cbd671772c9ce053a7050ddd29de170eb9efac7eZbigniew Jędrzejewski-Szmek /* Some libc APIs use (uid_t) -1 as special placeholder */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint safe_atou(const char *s, unsigned *ret_u) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek unsigned long l;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek if (!x || x == s || *x || errno)
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek return errno > 0 ? -errno : -EINVAL;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek if ((unsigned long) (unsigned) l != l)
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek *ret_u = (unsigned) l;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmekint safe_atoi(const char *s, int *ret_i) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!x || x == s || *x || errno)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return errno > 0 ? -errno : -EINVAL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if ((long) (int) l != l)
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmekint safe_atollu(const char *s, long long unsigned *ret_llu) {
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt unsigned long long l;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk if (!x || x == s || *x || errno)
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchukint safe_atolli(const char *s, long long int *ret_lli) {
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk l = strtoll(s, &x, 0);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (!x || x == s || *x || errno)
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchukint safe_atod(const char *s, double *ret_d) {
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek if (!x || x == s || *x || errno)
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek return errno ? -errno : -EINVAL;
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering *ret_d = (double) d;
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmekstatic size_t strcspn_escaped(const char *s, const char *reject) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek for (n=0; s[n]; n++) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek else if (s[n] == '\\')
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek/* Split a string into words. */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekchar *split(const char *c, size_t *l, const char *separator, bool quoted, char **state) {
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek current = *state ? *state : (char*) c;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!*current || *c == 0)
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (quoted && strchr("\'\"", *current)) {
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering *l = strcspn_escaped(current, (char[]){quotechar, '\0'});
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering *l = strcspn_escaped(current, separator);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering return (char*) current;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poetteringint get_parent_of_pid(pid_t pid, pid_t *_ppid) {
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering long unsigned ppid;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering const char *p;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering /* Let's skip the pid and comm fields. The latter is enclosed
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering * in () but does not escape any () in its value, so let's
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering * skip over it manually */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if ((long unsigned) (pid_t) ppid != ppid)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint get_starttime_of_pid(pid_t pid, unsigned long long *st) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_free_ char *line = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Let's skip the pid and comm fields. The latter is enclosed
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * in () but does not escape any () in its value, so let's
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * skip over it manually */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint fchmod_umask(int fd, mode_t m) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint get_process_state(pid_t pid) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_free_ char *line = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek p = procfs_file_alloca(pid, "stat");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek r = read_one_line_file(p, &line);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (sscanf(p, " %c", &state) != 1)
82499507b369fea3033a74c22813bf423301aef4Lennart Poettering return (unsigned char) state;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmekint get_process_comm(pid_t pid, char **name) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = read_one_line_file(p, name);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek _cleanup_fclose_ FILE *f = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek p = procfs_file_alloca(pid, "cmdline");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!GREEDY_REALLOC(r, allocated, len+2)) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r[len++] = isprint(c) ? c : ' ';
3a83211689bdf4ab617a4fb79e11980c50918123Shawn Landden bool space = false;
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering *(k++) = (char) c;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Kernel threads have no argv[] */
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering if (r == NULL || r[0] == 0) {
0a244b8ecb6dfcb381fe831dc2aa9bacb2c12975Lennart Poettering const char *p;
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering /* Kernel threads have an empty cmdline */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint get_process_capeff(pid_t pid, char **capeff) {
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek p = procfs_file_alloca(pid, "status");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek return get_status_field(p, "\nCapEff:", capeff);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmekint get_process_exe(pid_t pid, char **name) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek p = procfs_file_alloca(pid, "exe");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek return r == -ENOENT ? -ESRCH : r;
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poetteringstatic int get_process_id(pid_t pid, const char *field, uid_t *uid) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek _cleanup_fclose_ FILE *f = NULL;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek p = procfs_file_alloca(pid, "status");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek FOREACH_LINE(line, f, return -errno) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmekint get_process_uid(pid_t pid, uid_t *uid) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek return get_process_id(pid, "Uid:", uid);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmekint get_process_gid(pid_t pid, gid_t *gid) {
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering assert_cc(sizeof(uid_t) == sizeof(gid_t));
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poetteringchar *strnappend(const char *s, const char *suffix, size_t b) {
759c945a43577d56e85a927f15e7d9aaa94a4e4aColin Walterschar *strappend(const char *s, const char *suffix) {
82499507b369fea3033a74c22813bf423301aef4Lennart Poettering return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
edc3797f7cd9e37c24e5241cac3263e7c918f732Lennart Poetteringint readlinkat_malloc(int fd, const char *p, char **ret) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint readlink_malloc(const char *p, char **ret) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return readlinkat_malloc(AT_FDCWD, p, ret);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint readlink_and_make_absolute(const char *p, char **r) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_free_ char *target = NULL;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek k = file_in_same_dir(p, target);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint readlink_and_canonicalize(const char *p, char **r) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek j = readlink_and_make_absolute(p, &t);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint reset_all_signal_handlers(void) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek for (sig = 1; sig < _NSIG; sig++) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (sig == SIGKILL || sig == SIGSTOP)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* On Linux the first two RT signals are reserved by
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek * glibc, and sigaction() will return EINVAL for them. */
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek if ((sigaction(sig, &sa, NULL) < 0))
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering /* Drops trailing whitespace. Modifies the string in
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * place. Returns pointer to first non-space character */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek for (e = strchr(s, 0); e > s; e --)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekchar *delete_chars(char *s, const char *bad) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Drops all whitespace, regardless where in the string */
caa2f4c0c9613b2e02aafa308c8fb092576014a9Zbigniew Jędrzejewski-Szmek for (f = s, t = s; *f; f++) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekchar *file_in_same_dir(const char *path, const char *filename) {
433dd100442e8197868def975c6fd38b48dc6439Lukas Nykryn /* This removes the last component of path and appends
433dd100442e8197868def975c6fd38b48dc6439Lukas Nykryn * filename, unless the latter is absolute anyway or the
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt * former isn't */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!(r = new(char, e-path+1+k+1)))
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek memcpy(r+(e-path)+1, filename, k+1);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint rmdir_parents(const char *path, const char *stop) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Skip trailing slashes */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek while (l > 0 && path[l-1] == '/')
fc1d70af2101e16c9e6f3c5bfd5ab315ee9e6daeLennart Poettering /* Skip last component */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Skip trailing slashes */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek while (l > 0 && path[l-1] == '/')
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek static const char table[16] = "0123456789abcdef";
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekchar *hexmem(const void *p, size_t l) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek for (x = p; x < (const uint8_t*) p + l; x++) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek z = r = malloc((l + 1) / 2 + 1);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek for (x = p; x < p + l; x += 2) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (x+1 < p + l)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poetteringchar *cescape(const char *s) {
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering const char *f;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering /* Does C style string escaping. */
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering for (f = s, t = r; *f; f++)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = '\\';
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = '\\';
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = '\\';
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = '\\';
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = '\\';
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering *(t++) = '\\';
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering *(t++) = '\\';
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = '\\';
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = '\\';
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = '\\';
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = '\\';
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = '\'';
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* For special chars we prefer octal over
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering * hexadecimal encoding, simply because glib's
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering * g_strescape() does the same */
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = '\\';
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering *(t++) = octchar((unsigned char) *f >> 6);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = octchar((unsigned char) *f >> 3);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = octchar((unsigned char) *f);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poetteringchar *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix) {
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering const char *f;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering /* Undoes C style string escaping, and optionally prefixes it. */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek pl = prefix ? strlen(prefix) : 0;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering for (f = s, t = r + pl; f < s + length; f++) {
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (*f != '\\') {
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = '\a';
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = '\b';
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering *(t++) = '\f';
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *(t++) = '\n';
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering *(t++) = '\r';
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering *(t++) = '\t';
3bfd4e0c6341b0ef946d2198f089743fa99e0a97WaLyong Cho *(t++) = '\\';
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering /* This is an extension of the XDG syntax files */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* hexadecimal encoding */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (a < 0 || b < 0 || (a == 0 && b == 0)) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering /* Invalid escape code, let's take it literal then */
6203e07a83214a55bb1f88508fcda2005c601deaLennart Poettering *(t++) = (char) ((a << 4) | b);
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering /* octal encoding */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (a < 0 || b < 0 || c < 0 || (a == 0 && b == 0 && c == 0)) {
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering /* Invalid escape code, let's take it literal then */
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering *(t++) = '\\';
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering *(t++) = f[0];
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek *(t++) = (char) ((a << 6) | (b << 3) | c);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* premature end of string.*/
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering *(t++) = '\\';
b5884878a2874447b2a9f07f324a7cd909d96d48Lennart Poettering /* Invalid escape code, let's take it literal then */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekchar *cunescape_length(const char *s, size_t length) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return cunescape_length_with_prefix(s, length, NULL);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekchar *cunescape(const char *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return cunescape_length(s, strlen(s));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekchar *xescape(const char *s, const char *bad) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Escapes all chars in bad, in addition to \ and all special
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen * chars, in \xFF style escaping. May be reversed with
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen * cunescape. */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek for (f = s, t = r; *f; f++) {
b2fadec6048adb3596f2633cb7fe7a49f5937a18Zbigniew Jędrzejewski-Szmek if ((*f < ' ') || (*f >= 127) ||
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (*f == '\\') || strchr(bad, *f)) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering for (p = t; *p; p++)
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk_pure_ static bool ignore_file_allow_backup(const char *filename) {
6a0f1f6d5af7c7300d3db7a0ba2b068f8abd222bLennart Poettering return ignore_file_allow_backup(filename);
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering_pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering for (i = 0; i < n_fdset; i++)
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt return false;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poetteringint close_all_fds(const int except[], unsigned n_except) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(n_except == 0 || except);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* When /proc isn't available (for example in chroots)
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk * the fallback is brute forcing through the fd
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
b1389b0d0805392570085acc7cb10eafcf885405Zbigniew Jędrzejewski-Szmek if (safe_atoi(de->d_name, &fd) < 0)
d288f79fb4a2fe4a93cf99f74dacd2cebd3f2440Zbigniew Jędrzejewski-Szmek /* Let's better ignore this, just in case */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (fd_in_set(fd, except, n_except))
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering /* Valgrind has its own FD and doesn't want to have it closed */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekbool chars_intersect(const char *a, const char *b) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Returns true if any of the chars in a are in b. */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek for (p = a; *p; p++)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekbool fstype_is_network(const char *fstype) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek static const char table[] =
03ee5c38cb0da193dd08733fb4c0c2809cee6a99Lennart Poettering "glusterfs\0";
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek x = startswith(fstype, "fuse.");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return nulstr_contains(table, fstype);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (ioctl(fd, VT_ACTIVATE, vt) < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poetteringint read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (tcgetattr(fileno(f), &old_termios) >= 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering tcsetattr(fileno(f), TCSADRAIN, &old_termios);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering tcsetattr(fileno(f), TCSADRAIN, &old_termios);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint ask(char *ret, const char *replies, const char *text, ...) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fputs(ANSI_HIGHLIGHT_ON, stdout);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fputs(ANSI_HIGHLIGHT_OFF, stdout);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = read_one_char(stdin, &c, (usec_t) -1, &need_nl);
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering puts("Read unexpected character, please try again.");
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poetteringint reset_terminal_fd(int fd, bool switch_to_text) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Set terminal to some sane defaults */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* We leave locked terminal attributes untouched, so that
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * Plymouth may set whatever it wants to set, and we don't
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering * interfere with that. */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Disable exclusive mode, just in case */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Switch to text mode */
r = -errno;
goto finish;
r = -errno;
if (fd < 0)
return fd;
int fd, r;
if (fd >= 0)
return -errno;
return -errno;
if (fd < 0)
return -errno;
return -errno;
return -ENOTTY;
return fd;
ssize_t l;
return -errno;
return -errno;
int acquire_terminal(
const char *name,
bool fail,
bool force,
bool ignore_tiocstty_eperm,
if (notify < 0) {
r = -errno;
goto fail;
if (wd < 0) {
r = -errno;
goto fail;
if (notify >= 0) {
goto fail;
if (fd < 0)
return fd;
r = -errno;
goto fail;
ssize_t l;
struct inotify_event *e;
usec_t n;
r = -ETIMEDOUT;
goto fail;
goto fail;
r = -ETIMEDOUT;
goto fail;
r = -errno;
goto fail;
r = -EIO;
goto fail;
l -= step;
return fd;
fail:
int release_terminal(void) {
if (fd < 0)
return -errno;
r = -errno;
int r = 0, sig;
r = -errno;
r = -errno;
r = -errno;
r = -errno;
r = -errno;
void safe_close_pair(int p[]) {
assert(p);
p[0] = safe_close(p[0]);
ssize_t n = 0;
while (nbytes > 0) {
ssize_t k;
return n > 0 ? n : (k < 0 ? -errno : 0);
nbytes -= k;
ssize_t n = 0;
while (nbytes > 0) {
ssize_t k;
return n > 0 ? n : (k < 0 ? -errno : 0);
nbytes -= k;
struct table {
const char *suffix;
unsigned long long factor;
assert(t);
unsigned long long l2;
double frac = 0;
errno = 0;
if (errno > 0)
return -errno;
return -ERANGE;
return -EINVAL;
char *e2;
return -errno;
for (; e < e2; e++)
unsigned long long tmp;
return -ERANGE;
return -ERANGE;
r += tmp;
if ((unsigned long long) (off_t) r != r)
return -ERANGE;
if (i >= n_entries)
return -EINVAL;
*size = r;
return -errno;
int make_null_stdio(void) {
int null_fd;
if (null_fd < 0)
return -errno;
return -errno;
errno = 0;
return -errno;
if (!de)
return NULL;
if (dir != d) {
free(d);
return dir2;
return dir;
ssize_t k;
if (fd < 0)
if ((size_t) k != n)
return -EIO;
static bool srand_called = false;
uint8_t *q;
r = dev_urandom(p, n);
if (!srand_called) {
#ifdef HAVE_SYS_AUXV_H
void *auxv;
if (auxv)
x ^= *(unsigned*) auxv;
x ^= (unsigned) gettid();
srand(x);
srand_called = true;
for (q = p; q < (uint8_t*) p + n; q ++)
*q = rand();
if (saved_argc > 0) {
if (saved_argv[0])
if (!saved_argv[i])
int sig;
int sig;
return -errno;
char* gethostname_malloc(void) {
struct utsname u;
bool hostname_is_set(void) {
struct utsname u;
long bufsize;
char *name;
if (uid == 0)
if (bufsize <= 0)
if (!buf)
return NULL;
return NULL;
return name;
char* getlogname_malloc(void) {
char *getusername_malloc(void) {
return strdup(e);
assert(r);
return -ENOMEM;
free(s);
unsigned long ttynr;
return -EIO;
return -EIO;
return -ENOENT;
assert(r);
if (k != -ENOENT)
goto finish;
goto finish;
b = strdup(p);
return -ENOMEM;
if (_devnr)
int ret = 0;
errno = 0;
if (!de) {
return ret;
keep_around = false;
if (is_dir) {
int subdir_fd;
if (subdir_fd < 0) {
if (r < 0 && ret == 0)
ret = r;
if (!keep_around)
assert(s);
struct statfs s;
return -errno;
if (!is_temporary_fs(&s)) {
return -EPERM;
static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
int fd, r;
struct statfs s;
return -EPERM;
if (fd < 0) {
return -errno;
if (!dangerous) {
return -errno;
if (!is_temporary_fs(&s)) {
return -EPERM;
return -errno;
if (!dangerous) {
return -errno;
if (!is_temporary_fs(&s)) {
return -EPERM;
if (delete_root) {
r = -errno;
return -errno;
return -errno;
return -errno;
return -errno;
cpu_set_t *r;
if (!(r = CPU_ALLOC(n)))
return NULL;
if (ncpus)
*ncpus = n;
CPU_FREE(r);
return NULL;
int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) {
static bool prev_ephemeral;
return log_oom();
if (fd < 0)
return fd;
if (ellipse) {
free(s);
if (prev_ephemeral)
if (status) {
if (!ephemeral)
return -errno;
WORD,
char *r = NULL, *k;
for (e = format; *e; e ++) {
switch (state) {
case WORD:
case CURLY:
goto fail;
free(r);
goto fail;
free(r);
case VARIABLE:
k = strappend(r, t);
goto fail;
free(r);
goto fail;
free(r);
fail:
free(r);
return NULL;
return NULL;
if (!(m = strv_split_quoted(e))) {
r[k] = NULL;
strv_free(r);
return NULL;
m = NULL;
q = strv_length(m);
r[k] = NULL;
strv_free(r);
strv_free(m);
return NULL;
memcpy(r + k, m, q * sizeof(char*));
free(m);
strv_free(r);
return NULL;
r[k] = NULL;
return -errno;
return -EIO;
unsigned columns(void) {
return cached_columns;
safe_atoi(e, &c);
cached_columns = c;
return -errno;
return -EIO;
unsigned lines(void) {
return cached_lines;
safe_atou(e, &l);
cached_lines = l;
return cached_lines;
cached_columns = 0;
cached_lines = 0;
bool on_tty(void) {
return cached_on_tty;
struct stat a, b;
return -errno;
return -errno;
int running_in_chroot(void) {
int ret;
if (ret < 0)
return ret;
return ret == 0;
static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
size_t x;
assert(s);
return NULL;
memcpy(r, s, x);
size_t x;
assert(s);
if (ascii_is_valid(s))
c = utf8_encoded_to_unichar(i);
return NULL;
j = utf8_prev_char(j);
c = utf8_encoded_to_unichar(j);
return NULL;
assert(i <= j);
j = utf8_next_char(j);
len = i - s;
return NULL;
if (parents)
if (fd < 0)
return -errno;
if (mode > 0) {
return -errno;
return -errno;
return -errno;
size_t l;
assert(s);
l = strlen(s);
return strdup(s);
return strdup(s);
char *normalize_env_assignment(const char *s) {
char *eq, *r;
if (!eq) {
r = strdup(s);
return NULL;
t = strstrip(r);
if (!name)
return NULL;
return NULL;
if (!value)
return NULL;
r = NULL;
if (!status)
return -errno;
return -EPROTO;
return -EPROTO;
sync();
pause();
return -errno;
int nfd;
DIR *d;
if (nfd < 0)
return NULL;
return NULL;
int signal_from_string_try_harder(const char *s) {
int signo;
assert(s);
if (signo <= 0)
return signo;
return NULL;
return NULL;
return NULL;
char *fstab_node_to_udev_node(const char *p) {
assert(p);
return strdup(p);
return -EINVAL;
return -EINVAL;
return -EINVAL;
char *tty;
return NULL;
return NULL;
if (tty)
tty++;
char *tmp;
return tty;
if (!tty)
if (executor_pid < 0) {
} else if (executor_pid == 0) {
if (!pids) {
log_oom();
log_oom();
if (pid < 0) {
} else if (pid == 0) {
if (!argv) {
log_oom();
if (!nulstr)
bool plymouth_running(void) {
assert(s);
if (l < strlen(s))
static bool hostname_valid_char(char c) {
bool hostname_is_valid(const char *s) {
bool dot;
if (isempty(s))
for (p = s, dot = true; *p; p++) {
if (dot)
dot = true;
if (!hostname_valid_char(*p))
dot = false;
if (dot)
if (p-s > HOST_NAME_MAX)
bool dot;
for (p = s, d = s, dot = true; *p; p++) {
if (dot)
dot = true;
} else if (hostname_valid_char(*p)) {
dot = false;
if (dot && d > s)
bool machine_name_is_valid(const char *s) {
if (!hostname_is_valid(s))
return -errno;
return -errno;
FILE *f;
int fd;
return -ENOMEM;
if (fd < 0) {
free(t);
return -errno;
unlink(t);
free(t);
return -errno;
*_f = f;
*_temp_path = t;
return -errno;
if (fd < 0)
return fd;
int fd, r;
return -EINVAL;
if (fd < 0)
return fd;
return -EINVAL;
return -EINVAL;
if (fd < 0)
return fd;
return -errno;
if (fd < 0)
return fd;
return -ENOMEM;
return -errno;
unlink_noerrno(t);
return -errno;
return -ENOMEM;
return -errno;
unlink_noerrno(t);
return -errno;
return -ENOMEM;
return -errno;
unlink_noerrno(t);
return -errno;
size_t k;
return -EINVAL;
return -ENOMEM;
*path = f;
int get_user_creds(
const char **username,
const char **home,
const char **shell) {
struct passwd *p;
uid_t u;
if (uid)
*uid = 0;
if (gid)
*gid = 0;
if (home)
if (shell)
errno = 0;
p = getpwuid(u);
errno = 0;
if (uid)
if (gid)
if (home)
if (shell)
struct passwd *p;
if (uid == 0)
return NULL;
struct group *p;
if (gid == 0)
return NULL;
struct group *g;
if (gid)
*gid = 0;
errno = 0;
errno = 0;
if (gid)
int ngroups_max, r, i;
return -errno;
errno = 0;
if (k == GLOB_NOMATCH)
else if (k == GLOB_NOSPACE)
return -ENOMEM;
errno = 0;
if (k == GLOB_NOMATCH)
return -ENOENT;
else if (k == GLOB_NOSPACE)
return -ENOMEM;
assert(d);
return -errno;
return -errno;
errno = 0;
return -errno;
if (!de)
if (list) {
return -ENOMEM;
return -ENOMEM;
l[++n] = NULL;
if (list) {
*list = l;
char *strjoin(const char *x, ...) {
size_t l;
l = strlen(x);
size_t n;
n = strlen(t);
return NULL;
return NULL;
p = stpcpy(r, x);
p = stpcpy(p, t);
bool is_main_thread(void) {
return cached > 0;
return -ENOMEM;
free(p);
*ret = d;
return -ENOMEM;
free(p);
return -ENOENT;
return -ENOMEM;
r = read_one_line_file(p, &s);
free(p);
free(s);
return -EINVAL;
return -ENOMEM;
free(p);
return -ENOENT;
int file_is_priv_sticky(const char *p) {
assert(p);
return -errno;
static const char *const ioprio_class_table[] = {
static const char *const sigchld_code_table[] = {
static const char *const log_level_table[] = {
static const char* const sched_policy_table[] = {
static const char* const ip_tos_table[] = {
static const char *const __signal_table[] = {
#ifdef SIGSTKFLT
const char *name;
if (name)
return name;
return buf;
int signal_from_string(const char *s) {
int signo;
int offset = 0;
if (signo > 0)
return signo;
if (safe_atou(s, &u) >= 0) {
return signo;
bool kexec_loaded(void) {
bool loaded = false;
loaded = true;
free(s);
return loaded;
int strdup_or_null(const char *a, char **b) {
assert(b);
*b = NULL;
c = strdup(a);
return -ENOMEM;
case O_RDONLY:
return PROT_READ;
case O_WRONLY:
return PROT_WRITE;
case O_RDWR:
return -EINVAL;
const char *suffix;
} table[] = {
goto finish;
return buf;
assert(p);
r = malloc(l);
return NULL;
memcpy(r, p, l);
int r, value;
value = (int) n;
return -errno;
int r, value;
value = (int) n;
return -errno;
int fd;
if (agent_pid < 0)
return -errno;
if (agent_pid != 0) {
if (fd < 0) {
if (!stdout_is_tty)
if (!stderr_is_tty)
return -errno;
return -errno;
bool done = false;
size_t l;
const char *path;
return -errno;
c = getc(f);
done = true;
line[i] = c;
line[i] = 0;
if (!value)
return -ENOMEM;
} while (!done);
bool in_initrd(void) {
struct statfs s;
if (saved >= 0)
return saved;
* 1. the flag file /etc/initrd-release must exist
is_temporary_fs(&s);
return saved;
void warn_melody(void) {
if (fd < 0)
int make_console_stdio(void) {
int fd, r;
if (fd < 0) {
return fd;
struct passwd *p;
uid_t u;
if (e && path_is_absolute(e)) {
h = strdup(e);
return -ENOMEM;
*_h = h;
u = getuid();
return -ENOMEM;
*_h = h;
errno = 0;
p = getpwuid(u);
return -EINVAL;
return -ENOMEM;
*_h = h;
struct passwd *p;
uid_t u;
s = strdup(e);
return -ENOMEM;
*_s = s;
u = getuid();
return -ENOMEM;
*_s = s;
errno = 0;
p = getpwuid(u);
return -EINVAL;
return -ENOMEM;
*_s = s;
bool filename_is_safe(const char *p) {
if (isempty(p))
bool string_is_safe(const char *p) {
assert(p);
bool path_is_safe(const char *p) {
if (isempty(p))
int comparison;
u = nmemb;
if (comparison < 0)
u = idx;
else if (comparison > 0)
return NULL;
bool is_locale_utf8(void) {
const char *set;
if (cached_answer >= 0)
goto out;
cached_answer = true;
goto out;
if (!set) {
cached_answer = true;
goto out;
cached_answer = true;
goto out;
if (!set) {
cached_answer = true;
goto out;
out:
return (bool) cached_answer;
return NULL;
f = text;
goto oom;
l = nl;
f += old_len;
oom:
free(r);
return NULL;
FILE *f;
return NULL;
switch (state) {
case STATE_OTHER:
fputc(*i, f);
case STATE_ESCAPE:
fputc(*i, f);
case STATE_BRACKET:
if (ferror(f)) {
fclose(f);
return NULL;
fclose(f);
if (_isz)
return obuf;
int on_ac_power(void) {
return -errno;
ssize_t n;
errno = 0;
return -errno;
if (!de)
if (device < 0) {
return -errno;
if (fd < 0) {
return -errno;
return -errno;
if (fd < 0) {
return -errno;
return -errno;
return -EIO;
found_online = true;
found_offline = true;
return -EIO;
static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
return -ENOMEM;
FILE *f;
if (root)
return -ENOMEM;
*_f = f;
return -errno;
return -ENOENT;
int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
FILE *f;
*_f = f;
return -errno;
if (!copy)
return -ENOMEM;
int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
FILE *f;
*_f = f;
return -errno;
return -ENOMEM;
char *strextend(char **x, ...) {
size_t f, l;
assert(x);
l = f = *x ? strlen(*x) : 0;
size_t n;
n = strlen(t);
return NULL;
return NULL;
p = stpcpy(p, t);
char *strrep(const char *s, unsigned n) {
size_t l;
assert(s);
l = strlen(s);
return NULL;
p = stpcpy(p, s);
assert(p);
return NULL;
q = realloc(*p, a);
return NULL;
uint8_t *q;
assert(p);
return NULL;
bool id128_is_valid(const char *s) {
size_t i, l;
l = strlen(s);
assert(s);
assert(l);
assert(r);
return -EINVAL;
return -EINVAL;
a = strndup(s, x - s);
return -ENOMEM;
free(a);
return -ENOMEM;
int shall_restore_state(void) {
char *w, *state;
size_t l;
memcpy(n, w, l);
k = parse_boolean(e);
char *w, *state;
size_t l;
word[l] = 0;
if (value)
*(value++) = 0;
if (r == -ENOENT)
return -EHOSTDOWN;
return -EIO;
return -EIO;
return -EIO;
if (mntns_fd) {
const char *mntns;
if (mntnsfd < 0)
return -errno;
if (pidns_fd) {
const char *pidns;
if (pidnsfd < 0)
return -errno;
if (netns_fd) {
const char *netns;
if (netnsfd < 0)
return -errno;
if (root_fd) {
const char *root;
if (rfd < 0)
return -errno;
if (pidns_fd)
if (mntns_fd)
if (netns_fd)
if (root_fd)
if (pidns_fd >= 0)
return -errno;
if (mntns_fd >= 0)
return -errno;
if (netns_fd >= 0)
return -errno;
if (root_fd >= 0) {
return -errno;
return -errno;
if (setresgid(0, 0, 0) < 0)
return -errno;
return -errno;
if (setresuid(0, 0, 0) < 0)
return -errno;
if (pid <= 0)
if (pid <= 0)
struct ucred u;
return -errno;
if (n != sizeof(struct ucred))
return -EIO;
if (u.pid <= 0)
return -ENODATA;
*ucred = u;
s = new0(char, n);
return -ENOMEM;
free(s);
return -errno;
s = new0(char, n);
return -ENOMEM;
free(s);
return -errno;
if (isempty(s)) {
free(s);
return -ENOTSUP;
*ret = s;
int fd;
if (fd < 0)
return -errno;
return fd;
int fd;
#ifdef O_TMPFILE
if (fd >= 0)
return fd;
if (fd < 0)
return fd;
unlink(p);
return fd;
return -errno;
log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path);
unsigned long personality_from_string(const char *p) {
#if defined(__x86_64__)
return PER_LINUX32;
return PER_LINUX;
return PER_LINUX;
const char* personality_to_string(unsigned long p) {
#if defined(__x86_64__)
if (p == PER_LINUX32)
if (p == PER_LINUX)
if (p == PER_LINUX)
return NULL;
long mem;
if (!haystack)
return NULL;
const uint8_t *b = p;
assert(s == 0 || b);
size_t i;
if (param) {
bool again;
again = false;
if (!proc_self_mountinfo)
return -errno;
&path);
if (k == EOF)
return -ENOMEM;
r = -errno;
again = true;
} while (again);
if (!cleaned)
return -ENOMEM;
if (!done)
return -ENOMEM;
bool top_autofs = false;
if (!todo)
return -ENOMEM;
if (!proc_self_mountinfo)
return -errno;
&path,
&type);
if (k == EOF)
return -ENOMEM;
p = NULL;
if (r == -EEXIST)
return -errno;
return -errno;
return -ENOMEM;
if (r == -EEXIST)
return -errno;
assert(f);
errno = 0;
fflush(f);
if (ferror(f))
char *tempfn_xxxxxx(const char *p) {
const char *fn;
size_t k;
assert(p);
return NULL;
k = fn - p;
char *tempfn_random(const char *p) {
const char *fn;
uint64_t u;
size_t k;
assert(p);
return NULL;
k = fn - p;
u = random_u64();