path-util.c revision b63bd1090bf6ce79b6757c3f8f4172a367854577
e29e7a7e7e824df5cde83993d64c901926e5b0e9William King/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
e29e7a7e7e824df5cde83993d64c901926e5b0e9William King This file is part of systemd.
e29e7a7e7e824df5cde83993d64c901926e5b0e9William King Copyright 2010-2012 Lennart Poettering
e29e7a7e7e824df5cde83993d64c901926e5b0e9William King systemd is free software; you can redistribute it and/or modify it
e29e7a7e7e824df5cde83993d64c901926e5b0e9William King under the terms of the GNU Lesser General Public License as published by
e29e7a7e7e824df5cde83993d64c901926e5b0e9William King the Free Software Foundation; either version 2.1 of the License, or
e29e7a7e7e824df5cde83993d64c901926e5b0e9William King (at your option) any later version.
e29e7a7e7e824df5cde83993d64c901926e5b0e9William King systemd is distributed in the hope that it will be useful, but
along with systemd; If not, see <http://www.gnu.org/licenses/>.
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <fcntl.h>
#include <dirent.h>
#include "macro.h"
#include "util.h"
#include "log.h"
#include "strv.h"
#include "path-util.h"
#include "missing.h"
bool path_is_absolute(const char *p) {
bool is_path(const char *p) {
bool slash = false;
if (!*path)
return -EINVAL;
for (e = path; *e; e++) {
slash = true;
slash = false;
return -EINVAL;
if (p == path)
return -ENOMEM;
*_r = r;
char **path_split_and_make_absolute(const char *p) {
assert(p);
return NULL;
if (!path_strv_make_absolute_cwd(l)) {
strv_free(l);
return NULL;
assert(p);
return strdup(p);
char *path_make_absolute_cwd(const char *p) {
assert(p);
if (path_is_absolute(p))
return strdup(p);
if (!cwd)
return NULL;
unsigned n_parents;
return -EINVAL;
return -EINVAL;
size_t a;
size_t b;
if (!*from_dir) {
if (!*to_path)
return -ENOMEM;
*_r = r;
if (!*to_path)
from_dir += a;
to_path += b;
for (n_parents = 0;;) {
if (!*from_dir)
n_parents++;
return -ENOMEM;
*_r = r;
char **path_strv_make_absolute_cwd(char **l) {
STRV_FOREACH(s, l) {
t = path_make_absolute_cwd(*s);
return NULL;
free(*s);
bool enomem = false;
if (strv_isempty(l))
STRV_FOREACH(s, l) {
if (!path_is_absolute(*s)) {
free(*s);
if (prefix) {
orig = *s;
enomem = true;
errno = 0;
u = canonicalize_file_name(t);
if (prefix) {
u = orig;
free(t);
free(t);
enomem = true;
} else if (prefix) {
free(t);
t = strdup(x);
free(u);
enomem = true;
u = orig;
free(t);
l[k] = NULL;
if (enomem)
return NULL;
if (strv_isempty(l))
return NULL;
return strv_uniq(l);
bool slash = false;
slash = true;
if (slash) {
slash = false;
return path;
return NULL;
size_t a, b;
if (*prefix == 0)
return (char*) path;
if (*path == 0)
return NULL;
return NULL;
return NULL;
path += a;
prefix += b;
bool path_equal(const char *a, const char *b) {
assert(a);
assert(b);
size_t j, k;
if (memcmp(a, b, j) != 0)
NULL);
NULL);
union file_handle_union h = {
struct stat a, b;
goto fallback;
return -errno;
return -errno;
if (allow_symlink)
r = stat(t, &a);
r = lstat(t, &a);
return -errno;
return -errno;
return -errno;
/* We use /usr/lib/os-release as flag file if something is an OS */
return -errno;
if (filename) {
return -ENOMEM;
*filename = p;
const char *path;
size_t l;
if (!path)
return -ENOMEM;
if (filename) {
p = NULL;
return -ENOENT;
bool changed = false;
usec_t u;
if (*timestamp >= u)
if (update) {
*timestamp = u;
changed = true;
return changed;
const char *checker;
r = readlink_malloc(p, &d);
return -ENOENT;