util.c revision fecc80c1ba2eed9dadb9a10c15508c356bcc5fc1
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek This file is part of systemd.
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek Copyright 2010 Lennart Poettering
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek (at your option) any later version.
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekstatic volatile unsigned cached_columns = 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekstatic volatile unsigned cached_lines = 0;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek static thread_local size_t pgsz = 0;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekbool streq_ptr(const char *a, const char *b) {
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek /* Like streq(), but tries to make sense of NULL pointers */
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekchar* endswith(const char *s, const char *postfix) {
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek return (char*) s + sl;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek if (memcmp(s + sl - pl, postfix, pl) != 0)
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekbool first_word(const char *s, const char *word) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return s[wl] == 0 ||
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek * Just ignore EINTR; a retry loop is the wrong
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek * thing to do on Linux.
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek * https://bugzilla.gnome.org/show_bug.cgi?id=682819
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek * Like close_nointr() but cannot fail. Guarantees errno is
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek * unchanged. Is a NOP with negative fds passed, and returns
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek * -1, so that it can be used in this syntax:
b88a40a7e592e0a4a2e6e8eb1ed3721989ba5d0ePhilippe De Swert * fd = safe_close(fd);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek /* The kernel might return pretty much any error code
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek * via close(), but the fd will be closed anyway. The
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek * only condition we want to check for here is whether
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek * the fd was invalid at all... */
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek assert_se(close_nointr(fd) != -EBADF);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekvoid close_many(const int fds[], unsigned n_fd) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek for (i = 0; i < n_fd; i++)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekint unlink_noerrno(const char *path) {
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmekint parse_boolean(const char *v) {
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || strcaseeq(v, "on"))
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || strcaseeq(v, "off"))
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint parse_pid(const char *s, pid_t* ret_pid) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek unsigned long ul = 0;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekint parse_uid(const char *s, uid_t* ret_uid) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek unsigned long ul = 0;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek /* Some libc APIs use (uid_t) -1 as special placeholder */
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint safe_atou(const char *s, unsigned *ret_u) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek unsigned long l;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!x || x == s || *x || errno)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return errno > 0 ? -errno : -EINVAL;
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek if ((unsigned long) (unsigned) l != l)
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek *ret_u = (unsigned) l;
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmekint safe_atoi(const char *s, int *ret_i) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!x || x == s || *x || errno)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return errno > 0 ? -errno : -EINVAL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if ((long) (int) l != l)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekint safe_atollu(const char *s, long long unsigned *ret_llu) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek unsigned long long l;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (!x || x == s || *x || errno)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return errno ? -errno : -EINVAL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint safe_atolli(const char *s, long long int *ret_lli) {
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek if (!x || x == s || *x || errno)
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek return errno ? -errno : -EINVAL;
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmekint safe_atod(const char *s, double *ret_d) {
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek RUN_WITH_LOCALE(LC_NUMERIC_MASK, "C") {
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek if (!x || x == s || *x || errno)
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek return errno ? -errno : -EINVAL;
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmekstatic size_t strcspn_escaped(const char *s, const char *reject) {
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek for (n=0; s[n]; n++) {
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek else if (s[n] == '\\')
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek/* Split a string into words. */
5bc891206dd8eb4e4df58f502b0184b8426caf22Zbigniew Jędrzejewski-Szmekchar *split(const char *c, size_t *l, const char *separator, bool quoted, char **state) {
5bc891206dd8eb4e4df58f502b0184b8426caf22Zbigniew Jędrzejewski-Szmek current = *state ? *state : (char*) c;
5bc891206dd8eb4e4df58f502b0184b8426caf22Zbigniew Jędrzejewski-Szmek if (!*current || *c == 0)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek current += strspn(current, separator);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (quoted && strchr("\'\"", *current)) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek *l = strcspn_escaped(current, (char[]){quotechar, '\0'});
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek *l = strcspn_escaped(current, separator);
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek *l = strcspn(current, separator);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekint get_parent_of_pid(pid_t pid, pid_t *_ppid) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek _cleanup_free_ char *line = NULL;
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek p = procfs_file_alloca(pid, "stat");
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek r = read_one_line_file(p, &line);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek /* Let's skip the pid and comm fields. The latter is enclosed
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek * in () but does not escape any () in its value, so let's
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek * skip over it manually */
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if ((long unsigned) (pid_t) ppid != ppid)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint get_starttime_of_pid(pid_t pid, unsigned long long *st) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek _cleanup_free_ char *line = NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek p = procfs_file_alloca(pid, "stat");
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek r = read_one_line_file(p, &line);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek /* Let's skip the pid and comm fields. The latter is enclosed
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek * in () but does not escape any () in its value, so let's
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek * skip over it manually */
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekint get_process_state(pid_t pid) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek _cleanup_free_ char *line = NULL;
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek p = procfs_file_alloca(pid, "stat");
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek r = read_one_line_file(p, &line);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek if (sscanf(p, " %c", &state) != 1)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return (unsigned char) state;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekint get_process_comm(pid_t pid, char **name) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek p = procfs_file_alloca(pid, "comm");
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = read_one_line_file(p, name);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekint get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek _cleanup_fclose_ FILE *f = NULL;
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek p = procfs_file_alloca(pid, "cmdline");
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek if (!GREEDY_REALLOC(r, allocated, len+2)) {
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek r[len++] = isprint(c) ? c : ' ';
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek *(k++) = (char) c;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek /* Kernel threads have no argv[] */
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r == NULL || r[0] == 0) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint is_kernel_thread(pid_t pid) {
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering const char *p;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek p = procfs_file_alloca(pid, "cmdline");
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek /* Kernel threads have an empty cmdline */
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekint get_process_capeff(pid_t pid, char **capeff) {
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek p = procfs_file_alloca(pid, "status");
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek return get_status_field(p, "\nCapEff:", capeff);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint get_process_exe(pid_t pid, char **name) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek p = procfs_file_alloca(pid, "exe");
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return r == -ENOENT ? -ESRCH : r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek d = endswith(*name, " (deleted)");
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekstatic int get_process_id(pid_t pid, const char *field, uid_t *uid) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek _cleanup_fclose_ FILE *f = NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek p = procfs_file_alloca(pid, "status");
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek FOREACH_LINE(line, f, return -errno) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint get_process_uid(pid_t pid, uid_t *uid) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return get_process_id(pid, "Uid:", uid);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekint get_process_gid(pid_t pid, gid_t *gid) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert_cc(sizeof(uid_t) == sizeof(gid_t));
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return get_process_id(pid, "Gid:", gid);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekchar *strnappend(const char *s, const char *suffix, size_t b) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekchar *strappend(const char *s, const char *suffix) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekint readlinkat_malloc(int fd, const char *p, char **ret) {
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;
return -ETIMEDOUT;
return -EIO;
if (need_nl)
*ret = c;
return -ETIMEDOUT;
return -EIO;
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 (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;
int nfd;
DIR *d;
if (nfd < 0)
return NULL;
return NULL;
int signal_from_string_try_harder(const char *s) {
int signo;
assert(s);
if (signo <= 0)
return signo;
return NULL;
return NULL;
return NULL;
char *fstab_node_to_udev_node(const char *p) {
assert(p);
return strdup(p);
return -EINVAL;
return -EINVAL;
return -EINVAL;
char *tty;
return NULL;
return NULL;
if (tty)
tty++;
char *tmp;
return tty;
if (!tty)
if (executor_pid < 0) {
} else if (executor_pid == 0) {
if (!pids) {
log_oom();
log_oom();
if (pid < 0) {
} else if (pid == 0) {
if (!argv) {
log_oom();
if (!nulstr)
bool plymouth_running(void) {
assert(s);
if (l < strlen(s))
static bool hostname_valid_char(char c) {
bool hostname_is_valid(const char *s) {
bool dot;
if (isempty(s))
for (p = s, dot = true; *p; p++) {
if (dot)
dot = true;
if (!hostname_valid_char(*p))
dot = false;
if (dot)
if (p-s > HOST_NAME_MAX)
bool dot;
for (p = s, d = s, dot = true; *p; p++) {
if (dot)
dot = true;
} else if (hostname_valid_char(*p)) {
dot = false;
if (dot && d > s)
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 string_has_cc(const char *p) {
assert(p);
bool path_is_safe(const char *p) {
if (isempty(p))
int comparison;
u = nmemb;
if (comparison < 0)
u = idx;
else if (comparison > 0)
return NULL;
bool is_locale_utf8(void) {
const char *set;
if (cached_answer >= 0)
goto out;
cached_answer = true;
goto out;
if (!set) {
cached_answer = true;
goto out;
cached_answer = true;
goto out;
if (!set) {
cached_answer = true;
goto out;
out:
return (bool) cached_answer;
return NULL;
f = text;
goto oom;
l = nl;
f += old_len;
oom:
free(r);
return NULL;
FILE *f;
return NULL;
switch (state) {
case STATE_OTHER:
fputc(*i, f);
case STATE_ESCAPE:
fputc(*i, f);
case STATE_BRACKET:
if (ferror(f)) {
fclose(f);
return NULL;
fclose(f);
if (_isz)
return obuf;
int on_ac_power(void) {
return -errno;
ssize_t n;
errno = 0;
return -errno;
if (!de)
if (device < 0) {
return -errno;
if (fd < 0) {
return -errno;
return -errno;
if (fd < 0) {
return -errno;
return -errno;
return -EIO;
found_online = true;
found_offline = true;
return -EIO;
static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
return -ENOMEM;
FILE *f;
if (root)
return -ENOMEM;
*_f = f;
return -errno;
return -ENOENT;
int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
FILE *f;
*_f = f;
return -errno;
if (!copy)
return -ENOMEM;
int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
FILE *f;
*_f = f;
return -errno;
return -ENOMEM;
char *strextend(char **x, ...) {
size_t f, l;
assert(x);
l = f = *x ? strlen(*x) : 0;
size_t n;
n = strlen(t);
return NULL;
return NULL;
p = stpcpy(p, t);
char *strrep(const char *s, unsigned n) {
size_t l;
assert(s);
l = strlen(s);
return NULL;
p = stpcpy(p, s);
assert(p);
return NULL;
q = realloc(*p, a);
return NULL;
uint8_t *q;
assert(p);
return NULL;
bool id128_is_valid(const char *s) {
size_t i, l;
l = strlen(s);
assert(s);
assert(l);
assert(r);
return -EINVAL;
return -EINVAL;
a = strndup(s, x - s);
return -ENOMEM;
free(a);
return -ENOMEM;
int shall_restore_state(void) {
char *w, *state;
size_t l;
memcpy(n, w, l);
k = parse_boolean(e);
char *w, *state;
size_t l;
word[l] = 0;
if (value)
*(value++) = 0;
if (r == -ENOENT)
return -EHOSTDOWN;
return -EIO;
return -EIO;
return -EIO;
if (mntns_fd) {
const char *mntns;
if (mntnsfd < 0)
return -errno;
if (pidns_fd) {
const char *pidns;
if (pidnsfd < 0)
return -errno;
if (netns_fd) {
const char *netns;
if (netnsfd < 0)
return -errno;
if (root_fd) {
const char *root;
if (rfd < 0)
return -errno;
if (pidns_fd)
if (mntns_fd)
if (netns_fd)
if (root_fd)
if (pidns_fd >= 0)
return -errno;
if (mntns_fd >= 0)
return -errno;
if (netns_fd >= 0)
return -errno;
if (root_fd >= 0) {
return -errno;
return -errno;
if (setresgid(0, 0, 0) < 0)
return -errno;
return -errno;
if (setresuid(0, 0, 0) < 0)
return -errno;
if (pid <= 0)
if (pid <= 0)
struct ucred u;
return -errno;
if (n != sizeof(struct ucred))
return -EIO;
if (u.pid <= 0)
return -ENODATA;
*ucred = u;
s = new0(char, n);
return -ENOMEM;
free(s);
return -errno;
s = new0(char, n);
return -ENOMEM;
free(s);
return -errno;
if (isempty(s)) {
free(s);
return -ENOTSUP;
*ret = s;
int fd;
if (fd < 0)
return -errno;
return fd;
int fd;
#ifdef O_TMPFILE
if (fd >= 0)
return fd;
if (fd < 0)
return fd;
unlink(p);
return fd;
return -errno;
log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path);
unsigned long personality_from_string(const char *p) {
#if defined(__x86_64__)
return PER_LINUX32;
return PER_LINUX;
return PER_LINUX;
const char* personality_to_string(unsigned long p) {
#if defined(__x86_64__)
if (p == PER_LINUX32)
if (p == PER_LINUX)
if (p == PER_LINUX)
return NULL;
long mem;
if (!haystack)
return NULL;
const uint8_t *b = p;
assert(s == 0 || b);
size_t i;
if (param) {
bool again;
again = false;
if (!proc_self_mountinfo)
return -errno;
&path);
if (k == EOF)
return -ENOMEM;
r = -errno;
again = true;
} while (again);
if (!cleaned)
return -ENOMEM;
if (!done)
return -ENOMEM;
bool top_autofs = false;
if (!todo)
return -ENOMEM;
if (!proc_self_mountinfo)
return -errno;
&path,
&type);
if (k == EOF)
return -ENOMEM;
p = NULL;
if (r == -EEXIST)
return -errno;
return -errno;
return -ENOMEM;
if (r == -EEXIST)
return -errno;
assert(f);
errno = 0;
fflush(f);
if (ferror(f))
char *tempfn_xxxxxx(const char *p) {
const char *fn;
size_t k;
assert(p);
return NULL;
k = fn - p;
char *tempfn_random(const char *p) {
const char *fn;
uint64_t u;
size_t k;
assert(p);
return NULL;
k = fn - p;
u = random_u64();