util.c revision 1a29929959fd8f59e19ce60c25d1a1f7d910fac0
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer This file is part of systemd.
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer Copyright 2010 Lennart Poettering
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer systemd is free software; you can redistribute it and/or modify it
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer under the terms of the GNU Lesser General Public License as published by
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt the Free Software Foundation; either version 2.1 of the License, or
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt (at your option) any later version.
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt systemd is distributed in the hope that it will be useful, but
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt WITHOUT ANY WARRANTY; without even the implied warranty of
4be4833ece2856e0cacc09f8f8b2c02b320751faMartin Pitt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier Lesser General Public License for more details.
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier You should have received a copy of the GNU Lesser General Public License
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier along with systemd; If not, see <http://www.gnu.org/licenses/>.
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic volatile unsigned cached_columns = 0;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic volatile unsigned cached_lines = 0;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierbool streq_ptr(const char *a, const char *b) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Like streq(), but tries to make sense of NULL pointers */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return streq(a, b);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!a && !b)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return false;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierchar* endswith(const char *s, const char *postfix) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return (char*) s + sl;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierchar* first_word(const char *s, const char *word) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Checks if the string starts with the specified word, either
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * followed by NUL or by whitespace. Returns a pointer to the
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * NUL or the first character after the whitespace. */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return (char*) s;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return (char*) p;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return (char*) p;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic size_t cescape_char(char c, char *buf) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* For special chars we prefer octal over
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * hexadecimal encoding, simply because glib's
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * g_strescape() does the same */
cffae62bcb6912fbaf1b7b282d9d170c9d308897Martin Pitt * Just ignore EINTR; a retry loop is the wrong thing to do on
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt * https://bugzilla.gnome.org/show_bug.cgi?id=682819
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * Like close_nointr() but cannot fail. Guarantees errno is
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * unchanged. Is a NOP with negative fds passed, and returns
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * -1, so that it can be used in this syntax:
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * fd = safe_close(fd);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* The kernel might return pretty much any error code
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * via close(), but the fd will be closed anyway. The
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * only condition we want to check for here is whether
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * the fd was invalid at all... */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevaliervoid close_many(const int fds[], unsigned n_fd) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier for (i = 0; i < n_fd; i++)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierint parse_boolean(const char *v) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierint parse_pid(const char *s, pid_t* ret_pid) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier unsigned long ul = 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unsigned long ul = 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Some libc APIs use (uid_t) -1 as special placeholder */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier unsigned long l;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer l = strtoul(s, &x, 0);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!x || x == s || *x || errno)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((unsigned long) (unsigned) l != l)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer *ret_u = (unsigned) l;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer l = strtol(s, &x, 0);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!x || x == s || *x || errno)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((long) (int) l != l)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unsigned long l;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer l = strtoul(s, &x, 0);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!x || x == s || *x || errno)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((unsigned long) (uint8_t) l != l)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unsigned long l;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer l = strtoul(s, &x, 0);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!x || x == s || *x || errno)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((unsigned long) (uint16_t) l != l)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer l = strtol(s, &x, 0);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!x || x == s || *x || errno)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((long) (int16_t) l != l)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerint safe_atollu(const char *s, long long unsigned *ret_llu) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer unsigned long long l;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer l = strtoull(s, &x, 0);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!x || x == s || *x || errno)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerint safe_atolli(const char *s, long long int *ret_lli) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer long long l;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer l = strtoll(s, &x, 0);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!x || x == s || *x || errno)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer double d = 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!x || x == s || *x || errno)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer *ret_d = (double) d;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic size_t strcspn_escaped(const char *s, const char *reject) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer bool escaped = false;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer for (n=0; s[n]; n++) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else if (s[n] == '\\')
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* if s ends in \, return index of previous char */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer/* Split a string into words. */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerconst char* split(const char **state, size_t *l, const char *separator, bool quoted) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* right quote missing or garbage at the end*/
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } else if (quoted) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerint get_parent_of_pid(pid_t pid, pid_t *_ppid) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer long unsigned ppid;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *p;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Let's skip the pid and comm fields. The latter is enclosed
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * in () but does not escape any () in its value, so let's
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * skip over it manually */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerint get_starttime_of_pid(pid_t pid, unsigned long long *st) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *p;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Let's skip the pid and comm fields. The latter is enclosed
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * in () but does not escape any () in its value, so let's
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * skip over it manually */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerchar *truncate_nl(char *s) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *p;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return (unsigned char) state;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *p;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerint get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char *r = NULL, *k;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *p;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer bool space = false;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer *(k++) = ' ';
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer *(k++) = (char) c;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Kernel threads have no argv[] */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *p;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Kernel threads have an empty cmdline */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerint get_process_capeff(pid_t pid, char **capeff) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *p;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return get_status_field(p, "\nCapEff:", capeff);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic int get_process_link_contents(const char *proc_file, char **name) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer const char *p;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic int get_process_id(pid_t pid, const char *field, uid_t *uid) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer const char *p;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer const char *p;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer const char *p;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerint get_process_environ(pid_t pid, char **environ) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer const char *p;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (!GREEDY_REALLOC(outcome, allocated, sz + 5))
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (c == '\0')
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerchar *strnappend(const char *s, const char *suffix, size_t b) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerchar *strappend(const char *s, const char *suffix) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerint readlinkat_malloc(int fd, const char *p, char **ret) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer c = new(char, l);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (n < 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerint readlink_malloc(const char *p, char **ret) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerint readlink_and_make_absolute(const char *p, char **r) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerint readlink_and_canonicalize(const char *p, char **r) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char *t, *s;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* These two cannot be caught... */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* On Linux the first two RT signals are reserved by
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * glibc, and sigaction() will return EINVAL for them. */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerchar *strstrip(char *s) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Drops trailing whitespace. Modifies the string in
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * place. Returns pointer to first non-space character */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer 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) {
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]);
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;
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;
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);
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 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 -errno;
return -EIO;
unsigned lines(void) {
return cached_lines;
(void) 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) {
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)
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;
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[] = {
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);
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) {
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;
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;
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;