path-util.c revision 9c4615fb09f559642742d3698ecb5a430c698230
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd This file is part of systemd.
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd Copyright 2010-2012 Lennart Poettering
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd systemd is free software; you can redistribute it and/or modify it
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd under the terms of the GNU Lesser General Public License as published by
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd the Free Software Foundation; either version 2.1 of the License, or
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd (at your option) any later version.
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd systemd is distributed in the hope that it will be useful, but
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd WITHOUT ANY WARRANTY; without even the implied warranty of
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd Lesser General Public License for more details.
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd You should have received a copy of the GNU Lesser General Public License
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd along with systemd; If not, see <http://www.gnu.org/licenses/>.
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd/* When we include libgen.h because we need dirname() we immediately
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd * undefine basename() since libgen.h defines it as a macro to the
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd * POSIX version which is really broken. We prefer GNU basename(). */
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecndbool path_is_absolute(const char *p) {
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd return p[0] == '/';
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecndbool is_path(const char *p) {
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecndint path_split_and_make_absolute(const char *p, char ***ret) {
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd if (r < 0) {
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecndchar *path_make_absolute(const char *p, const char *prefix) {
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd /* Makes every item in the list an absolute path by prepending
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd * the prefix, if specified and necessary */
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd return strdup(p);
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd /* Similar to path_make_absolute(), but prefixes with the
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd * current working directory. */
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecndint path_make_relative(const char *from_dir, const char *to_path, char **_r) {
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd char *r, *p;
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd /* Strips the common part, and adds ".." elements as necessary. */
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd /* Skip the common part. */
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd for (;;) {
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd /* from_dir equals to_path. */
62664c6703ed9e8d8f4f8e4c5f5e893559ecefecnd /* from_dir is a parent directory of to_path. */
from_dir += a;
to_path += b;
for (n_parents = 0;;) {
if (!*from_dir)
n_parents++;
return -ENOMEM;
*_r = r;
int path_strv_make_absolute_cwd(char **l) {
STRV_FOREACH(s, l) {
r = path_make_absolute_cwd(*s, &t);
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;
free(u);
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;
int path_compare(const char *a, const char *b) {
assert(a);
assert(b);
size_t j, k;
bool path_equal(const char *a, const char *b) {
return path_compare(a, b) == 0;
bool path_equal_or_files_same(const char *a, const char *b) {
NULL);
NULL);
int last_error, r;
return -errno;
if (ret) {
p = DEFAULT_PATH;
return -ENOMEM;
if (ret) {
j = NULL;
return last_error;
bool changed = false;
usec_t u;
if (*timestamp >= u)
if (update) {
*timestamp = u;
changed = true;
return changed;
if (r == -ENOENT)
r = readlink_malloc(p, &d);
const char *checker;
return -EINVAL;
const char *mkfs;
return -EINVAL;
size_t l;
path++;
n = new(char, l);
return NULL;
p = mfree(p);
*arg = p;
return NULL;
if (dir == d)
free(d);
return dir2;
bool filename_is_valid(const char *p) {
if (isempty(p))
if (e - p > FILENAME_MAX)
bool path_is_safe(const char *p) {
if (isempty(p))
char *e, *ret;
size_t k;
if (!ret)
return NULL;
return ret;