util.c revision 2eec67acbb00593e414549a7e5b35eb7dd776b1b
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering This file is part of systemd.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering Copyright 2010 Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering systemd is free software; you can redistribute it and/or modify it
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering under the terms of the GNU Lesser General Public License as published by
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering (at your option) any later version.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering systemd is distributed in the hope that it will be useful, but
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering Lesser General Public License for more details.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering You should have received a copy of the GNU Lesser General Public License
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering/* When we include libgen.h because we need dirname() we immediately
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering * undefine basename() since libgen.h defines it as a macro to the XDG
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering * version which is really broken. */
178cc7700c23ac088cd7190d7854282075028d91Lennart Poetteringstatic volatile unsigned cached_columns = 0;
178cc7700c23ac088cd7190d7854282075028d91Lennart Poetteringstatic volatile unsigned cached_lines = 0;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringbool streq_ptr(const char *a, const char *b) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering /* Like streq(), but tries to make sense of NULL pointers */
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringchar* endswith(const char *s, const char *postfix) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return (char*) s + sl;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (memcmp(s + sl - pl, postfix, pl) != 0)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringchar* first_word(const char *s, const char *word) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering const char *p;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering /* Checks if the string starts with the specified word, either
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering * followed by NUL or by whitespace. Returns a pointer to the
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering * NUL or the first character after the whitespace. */
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return (char*) s;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return (char*) p;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return (char*) p;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringstatic size_t cescape_char(char c, char *buf) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering /* For special chars we prefer octal over
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering * hexadecimal encoding, simply because glib's
e88baee88fad8bc59d33b55a7a2d640ef9e16cd6Zbigniew Jędrzejewski-Szmek * g_strescape() does the same */
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering *(buf++) = octchar((unsigned char) c >> 6);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering *(buf++) = octchar((unsigned char) c >> 3);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering * Just ignore EINTR; a retry loop is the wrong thing to do on
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering * https://bugzilla.gnome.org/show_bug.cgi?id=682819
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering * Like close_nointr() but cannot fail. Guarantees errno is
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering * unchanged. Is a NOP with negative fds passed, and returns
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering * -1, so that it can be used in this syntax:
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering * fd = safe_close(fd);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering /* The kernel might return pretty much any error code
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering * via close(), but the fd will be closed anyway. The
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering * only condition we want to check for here is whether
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering * the fd was invalid at all... */
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poetteringvoid close_many(const int fds[], unsigned n_fd) {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering for (i = 0; i < n_fd; i++)
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poetteringint parse_boolean(const char *v) {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poetteringint parse_pid(const char *s, pid_t* ret_pid) {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering unsigned long ul = 0;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringint parse_uid(const char *s, uid_t* ret_uid) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering unsigned long ul = 0;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering /* Some libc APIs use UID_INVALID as special placeholder */
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringint safe_atou(const char *s, unsigned *ret_u) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering unsigned long l;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (!x || x == s || *x || errno)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if ((unsigned long) (unsigned) l != l)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering *ret_u = (unsigned) l;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringint safe_atoi(const char *s, int *ret_i) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering l = strtol(s, &x, 0);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (!x || x == s || *x || errno)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if ((long) (int) l != l)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringint safe_atou8(const char *s, uint8_t *ret) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering unsigned long l;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (!x || x == s || *x || errno)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if ((unsigned long) (uint8_t) l != l)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringint safe_atou16(const char *s, uint16_t *ret) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering unsigned long l;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (!x || x == s || *x || errno)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if ((unsigned long) (uint16_t) l != l)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringint safe_atoi16(const char *s, int16_t *ret) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering l = strtol(s, &x, 0);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (!x || x == s || *x || errno)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if ((long) (int16_t) l != l)
178cc7700c23ac088cd7190d7854282075028d91Lennart Poetteringint safe_atollu(const char *s, long long unsigned *ret_llu) {
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering unsigned long long l;
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering if (!x || x == s || *x || errno)
char *x = NULL;
assert(s);
errno = 0;
l = strtoll(s, &x, 0);
if (!x || x == s || *x || errno)
*ret_lli = l;
char *x = NULL;
assert(s);
return -errno;
errno = 0;
if (!x || x == s || *x || errno) {
*ret_d = (double) d;
bool escaped = false;
if (escaped)
escaped = false;
escaped = true;
return n - escaped;
const char *current;
if (!*current) {
return NULL;
if (!*current) {
return NULL;
return NULL;
} else if (quoted) {
return NULL;
return current;
long unsigned ppid;
if (pid == 0) {
return -EIO;
return -EIO;
return -ERANGE;
mode_t u;
umask(u);
char *truncate_nl(char *s) {
assert(s);
char state;
return -EIO;
return -EIO;
return (unsigned char) state;
if (r == -ENOENT)
return -ESRCH;
char *r = NULL, *k;
return -errno;
if (max_length == 0) {
free(r);
return -ENOMEM;
if (len > 0)
bool space = false;
return -ENOMEM;
if (isprint(c)) {
if (space) {
left--;
space = false;
left--;
space = true;
if (isempty(r)) {
free(r);
if (!comm_fallback)
return -ENOENT;
return -ENOMEM;
*line = r;
bool eof;
FILE *f;
if (pid == 0)
return -errno;
fclose(f);
if (count <= 0)
if (pid == 0)
return getuid();
return -errno;
return -EIO;
return -errno;
return -ENOMEM;
size_t a;
if (!s && !suffix)
if (!suffix)
return strdup(s);
assert(s);
a = strlen(s);
return NULL;
return NULL;
memcpy(r, s, a);
assert(p);
ssize_t n;
c = new(char, l);
return -ENOMEM;
r = -errno;
free(c);
*ret = c;
free(c);
char *value;
if (!value)
return -ENOENT;
if (!value)
return -ENOMEM;
int readlink_and_make_absolute(const char *p, char **r) {
assert(p);
assert(r);
return -ENOMEM;
int readlink_and_canonicalize(const char *p, char **r) {
assert(p);
assert(r);
j = readlink_and_make_absolute(p, &t);
s = canonicalize_file_name(t);
free(t);
path_kill_slashes(*r);
int reset_all_signal_handlers(void) {
int sig, r = 0;
r = -errno;
int reset_signal_mask(void) {
return -errno;
return -errno;
char *strstrip(char *s) {
for (e = strchr(s, 0); e > s; e --)
char *e, *ret;
size_t k;
if (!ret)
return NULL;
return ret;
size_t l;
return -ENOMEM;
free(t);
r = rmdir(t);
free(t);
return -errno;
char hexchar(int x) {
int unhexchar(char c) {
return -EINVAL;
const uint8_t *x;
return NULL;
for (x = p; x < (const uint8_t*) p + l; x++) {
uint8_t *r, *z;
assert(p);
return NULL;
a = unhexchar(x[0]);
char octchar(int x) {
int unoctchar(char c) {
return -EINVAL;
char decchar(int x) {
int undecchar(char c) {
return -EINVAL;
char *cescape(const char *s) {
assert(s);
return NULL;
t += cescape_char(*f, t);
assert(s);
return NULL;
if (prefix)
a = unoctchar(f[0]);
char *cunescape(const char *s) {
assert(s);
return NULL;
*(t++) = hexchar(*f);
char *ascii_strlower(char *t) {
assert(t);
if (flags < 0)
return -errno;
if (nonblock)
return -errno;
if (flags < 0)
return -errno;
if (cloexec)
return -errno;
for (i = 0; i < n_fdset; i++)
int fd;
r = -errno;
r = -errno;
bool chars_intersect(const char *a, const char *b) {
if (strchr(b, *p))
static const char table[] =
fstype = x;
if (fd < 0)
return -errno;
if (vt < 0) {
return -errno;
return -errno;
assert(f);
size_t k;
if (t != USEC_INFINITY) {
return -ETIMEDOUT;
return -EIO;
if (need_nl)
*ret = c;
if (t != USEC_INFINITY) {
return -ETIMEDOUT;
errno = 0;
return -EBADMSG;
if (need_nl)
*need_nl = false;
bool need_nl = true;
if (on_tty())
if (on_tty())
if (r == -EBADMSG) {
if (need_nl)
*ret = c;
if (on_tty())
if (on_tty())
errno = 0;
return -ENOMEM;
*ret = s;
if (switch_to_text)
r = -errno;
goto finish;
r = -errno;
if (fd < 0)
return fd;
int fd, r;
if (fd >= 0)
return -errno;
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;
struct inotify_event *e;
ssize_t l;
usec_t n;
r = -ETIMEDOUT;
goto fail;
goto fail;
r = -ETIMEDOUT;
goto fail;
r = -errno;
goto fail;
r = -EIO;
goto fail;
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 : -errno;
nbytes -= k;
errno = 0;
while (nbytes > 0) {
ssize_t k;
return -errno;
return -EIO;
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;
int r, fd;
ssize_t k;
have_syscall = true;
have_syscall = false;
have_syscall = true;
return -errno;
return -EIO;
if (fd < 0)
if ((size_t) k != n)
return -EIO;
void initialize_srand(void) {
static bool srand_called = false;
#ifdef HAVE_SYS_AUXV_H
void *auxv;
if (srand_called)
#ifdef HAVE_SYS_AUXV_H
if (auxv)
x ^= *(unsigned*) auxv;
x ^= (unsigned) gettid();
srand(x);
srand_called = true;
uint8_t *q;
r = dev_urandom(p, n);
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);
char path[l];
return -ENOMEM;
*ret = c;
if (r != ERANGE)
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;
return is_temporary_fs(&s);
struct statfs s;
return -errno;
if (!is_temporary_fs(&s)) {
return -EPERM;
static int file_is_priv_sticky(const char *p) {
assert(p);
return -errno;
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;
char **ret, **i;
if (!ret)
return NULL;
r = strv_split_quoted(&m, e, true);
return NULL;
m = NULL;
q = strv_length(m);
strv_free(m);
return NULL;
ret = w;
free(m);
if (!ret[k]) {
return NULL;
return ret;
return -errno;
return -EIO;
unsigned columns(void) {
return cached_columns;
(void) safe_atoi(e, &c);
cached_columns = c;
return cached_columns;
return -errno;
return -EIO;
unsigned lines(void) {
return cached_lines;
(void) safe_atoi(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) {
const char *eq;
char *p, *name;
if (!eq) {
r = strdup(s);
return NULL;
t = strstrip(r);
if (!value)
return NULL;
if (!status)
return -errno;
return -EPROTO;
return -EPROTO;
sync();
pause();
return -errno;
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)
char **directory;
if (!pids)
return log_oom();
if (!seen)
return log_oom();
return log_oom();
if (!path)
return log_oom();
if (pid < 0) {
} else if (pid == 0) {
if (!argv) {
return log_oom();
char *name;
if (executor_pid < 0) {
} else if (executor_pid == 0) {
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 r, fd;
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 -errno;
unlink_noerrno(t);
return -errno;
return -errno;
unlink_noerrno(t);
return -errno;
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;
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;
return -EINVAL;
bool kexec_loaded(void) {
bool loaded = false;
loaded = true;
free(s);
return loaded;
case O_RDONLY:
return PROT_READ;
case O_WRONLY:
return PROT_WRITE;
case O_RDWR:
return -EINVAL;
const char *suffix;
} table[] = {
return NULL;
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;
if (agent_pid < 0) {
return -errno;
if (agent_pid != 0) {
int fd;
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);
if (isempty(p))
return ascii_is_valid(p);
if (isempty(p))
return ascii_is_valid(p);
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)
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_valid(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;
void init_gettext(void) {
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) {
p = line;
if (value)
*(value++) = 0;
bool found = false;
p = line;
if (value) {
found = true;
found = true;
if (value) {
return found;
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;
return -ENODATA;
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;
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);
return -errno;
if (!cleaned)
return -ENOMEM;
if (!done)
return -ENOMEM;
bool top_autofs = false;
unsigned long orig_flags;
if (!todo)
return -ENOMEM;
if (!proc_self_mountinfo)
return -errno;
&path,
&type);
if (k == EOF)
return -ENOMEM;
p = NULL;
if (r == -EEXIST)
return -errno;
orig_flags = 0;
return -errno;
return -ENOMEM;
if (r == -EEXIST)
orig_flags = 0;
return -errno;
assert(f);
errno = 0;
fflush(f);
if (ferror(f))
const char *fn;
assert(p);
return -EINVAL;
return -ENOMEM;
const char *fn;
uint64_t u;
assert(p);
return -EINVAL;
return -ENOMEM;
u = random_u64();
uint64_t u;
assert(p);
return -ENOMEM;
u = random_u64();
.l_start = 0,
.l_len = 0,
const char *path;
int fd, r;
if (root)
if (fd < 0)
return -errno;
return -errno;
return fd;
return -errno;
if (follow)
return -errno;
assert(p);
assert(*p);
switch (state) {
case START:
goto finish;
case VALUE:
goto finish;
return -ENOMEM;
s[sz++] = c;
case VALUE_ESCAPE:
if (relax)
goto finish;
return -EINVAL;
return -ENOMEM;
s[sz++] = c;
case SINGLE_QUOTE:
if (relax)
goto finish;
return -EINVAL;
return -ENOMEM;
s[sz++] = c;
case SINGLE_QUOTE_ESCAPE:
if (relax)
goto finish;
return -EINVAL;
return -ENOMEM;
s[sz++] = c;
case DOUBLE_QUOTE:
return -EINVAL;
return -ENOMEM;
s[sz++] = c;
case DOUBLE_QUOTE_ESCAPE:
if (relax)
goto finish;
return -EINVAL;
return -ENOMEM;
s[sz++] = c;
case SPACE:
goto finish;
goto finish;
s[sz] = 0;
*ret = s;
s = NULL;
int unquote_many_words(const char **p, ...) {
assert(p);
l = newa0(char*, n);
r = unquote_first_word(p, &l[c], false);
free(l[j]);
assert(v);
int free_and_strdup(char **p, const char *s) {
assert(p);
t = strdup(s);
return -ENOMEM;
t = NULL;
free(*p);
int sethostname_idempotent(const char *s) {
assert(s);
return -errno;
return -errno;
c = new(char, l);
return -ENOMEM;
*ret = c;
free(c);
return -errno;
free(c);
} control = {};
return -errno;
if (child < 0)
return -errno;
if (child == 0) {
int master;
if (master < 0)
return -EIO;
return -errno;
int *fds;
unsigned n_fds;
return -EIO;
return fds[0];
return -EIO;
ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
ssize_t l;
fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOATIME|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
if (fd < 0)
return -errno;
return -errno;
uint64_t u;
return -EIO;
ssize_t n;
return -errno;
if (n != sizeof(le))
return -EIO;
ssize_t n;
return -errno;
if (n != sizeof(le))
return -EIO;
ssize_t n;
assert(p);
return -errno;
if (n != sizeof(le))
return -EIO;
if (usec <= 0)
return -errno;
int same_fd(int a, int b) {
assert(a >= 0);
assert(b >= 0);
return -errno;
return -errno;
return -errno;
if (fa < 0)
return -errno;
if (fb < 0)
return -errno;
if (mask == 0)
return -errno;
return -errno;
assert(p);
if (mask == 0)
if (fd < 0)
return -errno;
return -errno;
assert(p);
if (fd < 0)
return -errno;
t = strdup(p);
return -ENOMEM;
if (fd < 0)
return -errno;
return -errno;
t = NULL;
const char *fn;
assert(p);
return -EINVAL;
if (f->path) {
if (f->fd >= 0 &&
f->operation = 0;
size_t n = 0;
while (sz > 0) {
sz--;
const uint8_t *q, *w, *e;
ssize_t l;
e = q + sz;
size_t n;
n = nul_length(q, e - q);
if ((n > run_length) ||
return -errno;
return -EIO;
return -errno;
return -errno;
return -EIO;
return q - (const uint8_t*) p;
if (!pid)
assert(p);
assert(*p);
if (with_facility)
size_t i;
if (!key)
for (i = 0; i < len; ++i)
return (ssize_t)i;