util.c revision a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek This file is part of systemd.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek Copyright 2010 Lennart Poettering
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek (at your option) any later version.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic volatile unsigned cached_columns = 0;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic volatile unsigned cached_lines = 0;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek static thread_local size_t pgsz = 0;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekbool streq_ptr(const char *a, const char *b) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* Like streq(), but tries to make sense of NULL pointers */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekchar* endswith(const char *s, const char *postfix) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return (char*) s + sl;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (memcmp(s + sl - pl, postfix, pl) != 0)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekbool first_word(const char *s, const char *word) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return s[wl] == 0 ||
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * Just ignore EINTR; a retry loop is the wrong
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * thing to do on Linux.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * https://bugzilla.gnome.org/show_bug.cgi?id=682819
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * Like close_nointr() but cannot fail. Guarantees errno is
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * unchanged. Is a NOP with negative fds passed, and returns
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * -1, so that it can be used in this syntax:
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * fd = safe_close(fd);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* The kernel might return pretty much any error code
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * via close(), but the fd will be closed anyway. The
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * only condition we want to check for here is whether
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * the fd was invalid at all... */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek assert_se(close_nointr(fd) != -EBADF);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekvoid close_many(const int fds[], unsigned n_fd) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek for (i = 0; i < n_fd; i++)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekint unlink_noerrno(const char *path) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekint parse_boolean(const char *v) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekint parse_pid(const char *s, pid_t* ret_pid) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek unsigned long ul = 0;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekint parse_uid(const char *s, uid_t* ret_uid) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek unsigned long ul = 0;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* Some libc APIs use (uid_t) -1 as special placeholder */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekint safe_atou(const char *s, unsigned *ret_u) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek unsigned long l;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (!x || x == s || *x || errno)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return errno > 0 ? -errno : -EINVAL;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if ((unsigned long) (unsigned) l != l)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek *ret_u = (unsigned) l;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekint safe_atoi(const char *s, int *ret_i) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (!x || x == s || *x || errno)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return errno > 0 ? -errno : -EINVAL;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if ((long) (int) l != l)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekint safe_atou8(const char *s, uint8_t *ret) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek unsigned long l;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (!x || x == s || *x || errno)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return errno > 0 ? -errno : -EINVAL;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if ((unsigned long) (uint8_t) l != l)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekint safe_atollu(const char *s, long long unsigned *ret_llu) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek unsigned long long l;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (!x || x == s || *x || errno)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return errno ? -errno : -EINVAL;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekint safe_atolli(const char *s, long long int *ret_lli) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (!x || x == s || *x || errno)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return errno ? -errno : -EINVAL;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekint safe_atod(const char *s, double *ret_d) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek RUN_WITH_LOCALE(LC_NUMERIC_MASK, "C") {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (!x || x == s || *x || errno)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return errno ? -errno : -EINVAL;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic size_t strcspn_escaped(const char *s, const char *reject) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek for (n=0; s[n]; n++) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek else if (s[n] == '\\')
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* if s ends in \, return index of previous char */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek/* Split a string into words. */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekconst char* split(const char **state, size_t *l, const char *separator, bool quoted) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek current += strspn(current, separator);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (quoted && strchr("\'\"", *current)) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek char quotechars[2] = {*current, '\0'};
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek *l = strcspn_escaped(current + 1, quotechars);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* right quote missing or garbage at the end*/
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek assert(current[*l + 1] == quotechars[0]);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek *l = strcspn_escaped(current, separator);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek *l = strcspn(current, separator);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekint get_parent_of_pid(pid_t pid, pid_t *_ppid) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek _cleanup_free_ char *line = NULL;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek p = procfs_file_alloca(pid, "stat");
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek r = read_one_line_file(p, &line);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* Let's skip the pid and comm fields. The latter is enclosed
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * in () but does not escape any () in its value, so let's
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek * skip over it manually */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if ((long unsigned) (pid_t) ppid != ppid)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekint get_starttime_of_pid(pid_t pid, unsigned long long *st) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek _cleanup_free_ char *line = NULL;
return -EIO;
return -EIO;
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 (r == NULL || r[0] == 0) {
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;
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);
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;
return -errno;
char *strstrip(char *s) {
for (e = strchr(s, 0); e > s; e --)
size_t k;
return NULL;
size_t l;
return -ENOMEM;
free(t);
r = rmdir(t);
free(t);
return -errno;
char hexchar(int x) {
int unhexchar(char c) {
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) {
char decchar(int x) {
int undecchar(char c) {
char *cescape(const char *s) {
assert(s);
return NULL;
*(t++) = octchar((unsigned char) *f);
assert(s);
if (prefix)
a = unoctchar(f[0]);
goto finish;
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;
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;
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();
if (!path) {
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) {
size_t l;
k = parse_boolean(e);
const 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();
.l_start = 0,
.l_len = 0,
const char *path;
int fd, r;
if (root)
if (fd < 0)
return -errno;
return -errno;
return fd;