src/shared/util.h \
src/shared/virt.c \
src/shared/virt.h \
+ src/shared/path-util.c \
+ src/shared/path-util.h \
src/shared/hashmap.c \
src/shared/hashmap.h \
src/shared/set.c \
#include "cgroup-show.h"
#include "cgroup-util.h"
#include "log.h"
+#include "path-util.h"
#include "util.h"
#include "pager.h"
#include "build.h"
#include <alloca.h>
#include <getopt.h>
+#include "path-util.h"
#include "util.h"
#include "hashmap.h"
#include "cgroup-util.h"
#include "special.h"
#include "label.h"
#include "mkdir.h"
+#include "path-util.h"
static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = {
[AUTOMOUNT_DEAD] = UNIT_INACTIVE,
#include "cgroup-util.h"
#include "log.h"
#include "strv.h"
+#include "path-util.h"
int cgroup_bonding_realize(CGroupBonding *b) {
int r;
#include "util.h"
#include "condition.h"
#include "virt.h"
+#include "path-util.h"
Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) {
Condition *c;
#include "unit-name.h"
#include "dbus-device.h"
#include "def.h"
+#include "path-util.h"
static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
[DEVICE_DEAD] = UNIT_INACTIVE,
#include "utmp-wtmp.h"
#include "def.h"
#include "loopback-setup.h"
+#include "path-util.h"
/* This assumes there is a 'tty' group */
#define TTY_MODE 0620
/* This resulting string must fit in 10 chars (i.e. the length
* of "/sbin/init") to look pretty in /bin/ps */
- p = file_name_from_path(path);
+ p = path_get_file_name(path);
if (isempty(p)) {
rename_process("(...)");
return;
}
if (!keep_stdout) {
- err = setup_output(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin);
+ err = setup_output(context, socket_fd, path_get_file_name(command->path), apply_tty_stdin);
if (err < 0) {
r = EXIT_STDOUT;
goto fail_child;
}
}
- err = setup_error(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin);
+ err = setup_error(context, socket_fd, path_get_file_name(command->path), apply_tty_stdin);
if (err < 0) {
r = EXIT_STDERR;
goto fail_child;
#include "unit-name.h"
#include "bus-errors.h"
#include "utf8.h"
+#include "path-util.h"
#ifndef HAVE_SYSV_COMPAT
int config_parse_warn_compat(
/* Add the file name we are currently looking at to
* the names of this unit, but only if it is a valid
* unit name. */
- name = file_name_from_path(*filename);
+ name = path_get_file_name(*filename);
if (unit_name_is_valid(name, true)) {
#include "virt.h"
#include "watchdog.h"
#include "cgroup-util.h"
+#include "path-util.h"
/* As soon as 16 units are in our GC queue, make sure to run a gc sweep */
#define GC_QUEUE_ENTRIES_MAX 16
}
if (!name)
- name = file_name_from_path(path);
+ name = path_get_file_name(path);
t = unit_name_to_type(name);
#include "set.h"
#include "strv.h"
#include "mkdir.h"
+#include "path-util.h"
#ifndef TTY_GID
#define TTY_GID 5
#include "log.h"
#include "strv.h"
#include "mkdir.h"
+#include "path-util.h"
#include "mount-setup.h"
#include "unit-name.h"
#include "dbus-mount.h"
#include "strv.h"
#include "util.h"
+#include "path-util.h"
#include "namespace.h"
#include "missing.h"
#include "dbus-path.h"
#include "special.h"
#include "bus-errors.h"
+#include "path-util.h"
static const UnitActiveState state_translation_table[_PATH_STATE_MAX] = {
[PATH_DEAD] = UNIT_INACTIVE,
#include "bus-errors.h"
#include "exit-status.h"
#include "def.h"
+#include "path-util.h"
#include "util.h"
#include "utf8.h"
goto finish;
}
- r = sysv_translate_facility(n, file_name_from_path(path), &m);
+ r = sysv_translate_facility(n, path_get_file_name(path), &m);
free(n);
if (r < 0)
goto finish;
}
- r = sysv_translate_facility(n, file_name_from_path(path), &m);
+ r = sysv_translate_facility(n, path_get_file_name(path), &m);
if (r < 0) {
log_error("[%s:%u] Failed to translate LSB dependency %s, ignoring: %s", path, line, n, strerror(-r));
#include "load-fragment.h"
#include "strv.h"
#include "mkdir.h"
+#include "path-util.h"
#include "unit-name.h"
#include "dbus-socket.h"
#include "missing.h"
#include "bus-errors.h"
#include "exit-status.h"
#include "def.h"
+#include "path-util.h"
static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
[SWAP_DEAD] = UNIT_INACTIVE,
#include "list.h"
#include "mount-setup.h"
#include "umount.h"
+#include "path-util.h"
#include "util.h"
typedef struct MountPoint {
#include "unit.h"
#include "macro.h"
#include "strv.h"
+#include "path-util.h"
#include "load-fragment.h"
#include "load-dropin.h"
#include "log.h"
assert(name || path);
if (!name)
- name = file_name_from_path(path);
+ name = path_get_file_name(path);
if (!unit_name_is_template(name)) {
*p = NULL;
if (specifier == 'r')
return strdup(u->manager->cgroup_hierarchy);
- if (parent_of_path(u->manager->cgroup_hierarchy, &p) < 0)
+ if (path_get_parent(u->manager->cgroup_hierarchy, &p) < 0)
return strdup("");
if (streq(p, "/")) {
if (u->unit_file_state < 0 && u->fragment_path)
u->unit_file_state = unit_file_get_state(
u->manager->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
- NULL, file_name_from_path(u->fragment_path));
+ NULL, path_get_file_name(u->fragment_path));
return u->unit_file_state;
}
#include "log.h"
#include "util.h"
+#include "path-util.h"
#include "strv.h"
#include "ask-password-api.h"
#include "def.h"
#include "journal-file.h"
#include "hashmap.h"
#include "list.h"
+#include "path-util.h"
#include "lookup3.h"
#include "compress.h"
#include "journal-internal.h"
bid, (unsigned long long) le64toh(o->entry.monotonic),
(unsigned long long) le64toh(o->entry.realtime),
(unsigned long long) le64toh(o->entry.xor_hash),
- file_name_from_path(j->current_file->path)) < 0)
+ path_get_file_name(j->current_file->path)) < 0)
return -ENOMEM;
return 1;
#include "dbus-common.h"
#include "strv.h"
#include "mkdir.h"
+#include "path-util.h"
#include "polkit.h"
#include "special.h"
#include "util.h"
#include "mkdir.h"
-
+#include "path-util.h"
#include "logind-inhibit.h"
Inhibitor* inhibitor_new(Manager *m, const char* id) {
return NULL;
}
- i->id = file_name_from_path(i->state_file);
+ i->id = path_get_file_name(i->state_file);
if (hashmap_put(m->inhibitors, i->id, i) < 0) {
free(i->state_file);
#include "logind-acl.h"
#include "util.h"
#include "mkdir.h"
+#include "path-util.h"
Seat *seat_new(Manager *m, const char *id) {
Seat *s;
return NULL;
}
- s->id = file_name_from_path(s->state_file);
+ s->id = path_get_file_name(s->state_file);
s->manager = m;
if (hashmap_put(m->seats, s->id, s) < 0) {
#include "strv.h"
#include "util.h"
#include "mkdir.h"
+#include "path-util.h"
#include "cgroup-util.h"
#include "logind-session.h"
return NULL;
}
- s->id = file_name_from_path(s->state_file);
+ s->id = path_get_file_name(s->state_file);
if (hashmap_put(m->sessions, s->id, s) < 0) {
free(s->state_file);
#include "util.h"
#include "sysfs-show.h"
+#include "path-util.h"
static int show_sysfs_one(
struct udev *udev,
#include "missing.h"
#include "cgroup-util.h"
#include "strv.h"
+#include "path-util.h"
#include "loopback-setup.h"
static char *arg_directory = NULL;
char *hn;
int r = 0;
- hn = file_name_from_path(arg_directory);
+ hn = path_get_file_name(arg_directory);
if (hn) {
hn = strdup(hn);
if (!hn)
#include "log.h"
#include "util.h"
+#include "path-util.h"
#include "set.h"
#include "mount-setup.h"
#include "exit-status.h"
#include "util.h"
#include "macro.h"
+#include "path-util.h"
#include "cgroup-util.h"
#include "cgroup-show.h"
}
if (last) {
- printf("%s\342\224\234 %s\n", prefix, file_name_from_path(last));
+ printf("%s\342\224\234 %s\n", prefix, path_get_file_name(last));
if (!p1) {
p1 = strappend(prefix, "\342\224\202 ");
show_cgroup_one_by_path(path, prefix, n_columns, !!last, kernel_threads);
if (last) {
- printf("%s\342\224\224 %s\n", prefix, file_name_from_path(last));
+ printf("%s\342\224\224 %s\n", prefix, path_get_file_name(last));
if (!p2) {
p2 = strappend(prefix, " ");
#include "set.h"
#include "macro.h"
#include "util.h"
+#include "path-util.h"
#include "strv.h"
int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) {
assert(controller);
assert(path);
- if ((r = parent_of_path(path, &parent)) < 0)
+ if ((r = path_get_parent(path, &parent)) < 0)
return r;
r = cg_migrate_recursive(controller, path, parent, false, true);
#include "missing.h"
#include "log.h"
#include "strv.h"
+#include "path-util.h"
#include "hashmap.h"
#include "conf-files.h"
goto finish;
}
- if (hashmap_put(h, file_name_from_path(p), p) <= 0) {
+ if (hashmap_put(h, path_get_file_name(p), p) <= 0) {
log_debug("Skip overridden file: %s.", p);
free(p);
}
s1 = *(char * const *)a;
s2 = *(char * const *)b;
- return strcmp(file_name_from_path(s1), file_name_from_path(s2));
+ return strcmp(path_get_file_name(s1), path_get_file_name(s2));
}
int conf_files_list_strv(char ***strv, const char *suffix, const char **dirs) {
goto finish;
}
- if (!strv_path_canonicalize(dirs)) {
+ if (!path_strv_canonicalize(dirs)) {
r = -ENOMEM;
goto finish;
}
#include "strv.h"
#include "log.h"
#include "utf8.h"
+#include "path-util.h"
int config_item_table_lookup(
void *table,
#include "mkdir.h"
#include "hashmap.h"
#include "set.h"
+#include "path-util.h"
#include "path-lookup.h"
#include "strv.h"
#include "unit-name.h"
found =
set_get(remove_symlinks_to, dest) ||
- set_get(remove_symlinks_to, file_name_from_path(dest));
+ set_get(remove_symlinks_to, path_get_file_name(dest));
if (found) {
if (path_is_absolute(name))
found_dest = path_equal(dest, name);
else
- found_dest = streq(file_name_from_path(dest), name);
+ found_dest = streq(path_get_file_name(dest), name);
free(dest);
char *path, *fn;
struct stat st;
- fn = file_name_from_path(*i);
+ fn = path_get_file_name(*i);
if (!path_is_absolute(*i) ||
!unit_name_is_valid_no_type(fn, true)) {
assert(name || path);
if (!name)
- name = file_name_from_path(path);
+ name = path_get_file_name(path);
if (!unit_name_is_valid_no_type(name, true))
return -EINVAL;
continue;
found:
- r = hashmap_put(h, file_name_from_path(f->path), f);
+ r = hashmap_put(h, path_get_file_name(f->path), f);
if (r < 0) {
free(f->path);
free(f);
#include "label.h"
#include "util.h"
+#include "path-util.h"
#ifdef HAVE_SELINUX
#include <selinux/selinux.h>
#include "util.h"
#include "mkdir.h"
#include "strv.h"
-
+#include "path-util.h"
#include "path-lookup.h"
int user_config_home(char **config_home) {
strv_free(r);
r = t;
- if (!strv_path_make_absolute_cwd(r))
+ if (!path_strv_make_absolute_cwd(r))
goto fail;
finish:
/* First priority is whatever has been passed to us via env
* vars */
if ((e = getenv("SYSTEMD_UNIT_PATH")))
- if (!(p->unit_path = split_path_and_make_absolute(e)))
+ if (!(p->unit_path = path_split_and_make_absolute(e)))
return -ENOMEM;
if (strv_isempty(p->unit_path)) {
}
if (p->unit_path)
- if (!strv_path_canonicalize(p->unit_path))
+ if (!path_strv_canonicalize(p->unit_path))
return -ENOMEM;
strv_uniq(p->unit_path);
- strv_path_remove_empty(p->unit_path);
+ path_strv_remove_empty(p->unit_path);
if (!strv_isempty(p->unit_path)) {
/* /etc/init.d/ compatibility does not matter to users */
if ((e = getenv("SYSTEMD_SYSVINIT_PATH")))
- if (!(p->sysvinit_path = split_path_and_make_absolute(e)))
+ if (!(p->sysvinit_path = path_split_and_make_absolute(e)))
return -ENOMEM;
if (strv_isempty(p->sysvinit_path)) {
}
if ((e = getenv("SYSTEMD_SYSVRCND_PATH")))
- if (!(p->sysvrcnd_path = split_path_and_make_absolute(e)))
+ if (!(p->sysvrcnd_path = path_split_and_make_absolute(e)))
return -ENOMEM;
if (strv_isempty(p->sysvrcnd_path)) {
}
if (p->sysvinit_path)
- if (!strv_path_canonicalize(p->sysvinit_path))
+ if (!path_strv_canonicalize(p->sysvinit_path))
return -ENOMEM;
if (p->sysvrcnd_path)
- if (!strv_path_canonicalize(p->sysvrcnd_path))
+ if (!path_strv_canonicalize(p->sysvrcnd_path))
return -ENOMEM;
strv_uniq(p->sysvinit_path);
strv_uniq(p->sysvrcnd_path);
- strv_path_remove_empty(p->sysvinit_path);
- strv_path_remove_empty(p->sysvrcnd_path);
+ path_strv_remove_empty(p->sysvinit_path);
+ path_strv_remove_empty(p->sysvrcnd_path);
if (!strv_isempty(p->sysvinit_path)) {
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010-2012 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ 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 <sys/statvfs.h>
+
+#include "macro.h"
+#include "util.h"
+#include "log.h"
+#include "strv.h"
+#include "path-util.h"
+
+bool path_is_absolute(const char *p) {
+ return p[0] == '/';
+}
+
+bool is_path(const char *p) {
+ return !!strchr(p, '/');
+}
+
+char *path_get_file_name(const char *p) {
+ char *r;
+
+ assert(p);
+
+ if ((r = strrchr(p, '/')))
+ return r + 1;
+
+ return (char*) p;
+}
+
+int path_get_parent(const char *path, char **_r) {
+ const char *e, *a = NULL, *b = NULL, *p;
+ char *r;
+ bool slash = false;
+
+ assert(path);
+ assert(_r);
+
+ if (!*path)
+ return -EINVAL;
+
+ for (e = path; *e; e++) {
+
+ if (!slash && *e == '/') {
+ a = b;
+ b = e;
+ slash = true;
+ } else if (slash && *e != '/')
+ slash = false;
+ }
+
+ if (*(e-1) == '/')
+ p = a;
+ else
+ p = b;
+
+ if (!p)
+ return -EINVAL;
+
+ if (p == path)
+ r = strdup("/");
+ else
+ r = strndup(path, p-path);
+
+ if (!r)
+ return -ENOMEM;
+
+ *_r = r;
+ return 0;
+}
+
+char **path_split_and_make_absolute(const char *p) {
+ char **l;
+ assert(p);
+
+ if (!(l = strv_split(p, ":")))
+ return NULL;
+
+ if (!path_strv_make_absolute_cwd(l)) {
+ strv_free(l);
+ return NULL;
+ }
+
+ return l;
+}
+
+char *path_make_absolute(const char *p, const char *prefix) {
+ assert(p);
+
+ /* Makes every item in the list an absolute path by prepending
+ * the prefix, if specified and necessary */
+
+ if (path_is_absolute(p) || !prefix)
+ return strdup(p);
+
+ return join(prefix, "/", p, NULL);
+}
+
+char *path_make_absolute_cwd(const char *p) {
+ char *cwd, *r;
+
+ assert(p);
+
+ /* Similar to path_make_absolute(), but prefixes with the
+ * current working directory. */
+
+ if (path_is_absolute(p))
+ return strdup(p);
+
+ if (!(cwd = get_current_dir_name()))
+ return NULL;
+
+ r = path_make_absolute(p, cwd);
+ free(cwd);
+
+ return r;
+}
+
+char **path_strv_make_absolute_cwd(char **l) {
+ char **s;
+
+ /* Goes through every item in the string list and makes it
+ * absolute. This works in place and won't rollback any
+ * changes on failure. */
+
+ STRV_FOREACH(s, l) {
+ char *t;
+
+ if (!(t = path_make_absolute_cwd(*s)))
+ return NULL;
+
+ free(*s);
+ *s = t;
+ }
+
+ return l;
+}
+
+char **path_strv_canonicalize(char **l) {
+ char **s;
+ unsigned k = 0;
+ bool enomem = false;
+
+ if (strv_isempty(l))
+ return l;
+
+ /* Goes through every item in the string list and canonicalize
+ * the path. This works in place and won't rollback any
+ * changes on failure. */
+
+ STRV_FOREACH(s, l) {
+ char *t, *u;
+
+ t = path_make_absolute_cwd(*s);
+ free(*s);
+
+ if (!t) {
+ enomem = true;
+ continue;
+ }
+
+ errno = 0;
+ u = canonicalize_file_name(t);
+ free(t);
+
+ if (!u) {
+ if (errno == ENOMEM || !errno)
+ enomem = true;
+
+ continue;
+ }
+
+ l[k++] = u;
+ }
+
+ l[k] = NULL;
+
+ if (enomem)
+ return NULL;
+
+ return l;
+}
+
+char **path_strv_remove_empty(char **l) {
+ char **f, **t;
+
+ if (!l)
+ return NULL;
+
+ for (f = t = l; *f; f++) {
+
+ if (dir_is_empty(*f) > 0) {
+ free(*f);
+ continue;
+ }
+
+ *(t++) = *f;
+ }
+
+ *t = NULL;
+ return l;
+}
+
+char *path_kill_slashes(char *path) {
+ char *f, *t;
+ bool slash = false;
+
+ /* Removes redundant inner and trailing slashes. Modifies the
+ * passed string in-place.
+ *
+ * ///foo///bar/ becomes /foo/bar
+ */
+
+ for (f = path, t = path; *f; f++) {
+
+ if (*f == '/') {
+ slash = true;
+ continue;
+ }
+
+ if (slash) {
+ slash = false;
+ *(t++) = '/';
+ }
+
+ *(t++) = *f;
+ }
+
+ /* Special rule, if we are talking of the root directory, a
+ trailing slash is good */
+
+ if (t == path && slash)
+ *(t++) = '/';
+
+ *t = 0;
+ return path;
+}
+
+bool path_startswith(const char *path, const char *prefix) {
+ assert(path);
+ assert(prefix);
+
+ if ((path[0] == '/') != (prefix[0] == '/'))
+ return false;
+
+ for (;;) {
+ size_t a, b;
+
+ path += strspn(path, "/");
+ prefix += strspn(prefix, "/");
+
+ if (*prefix == 0)
+ return true;
+
+ if (*path == 0)
+ return false;
+
+ a = strcspn(path, "/");
+ b = strcspn(prefix, "/");
+
+ if (a != b)
+ return false;
+
+ if (memcmp(path, prefix, a) != 0)
+ return false;
+
+ path += a;
+ prefix += b;
+ }
+}
+
+bool path_equal(const char *a, const char *b) {
+ assert(a);
+ assert(b);
+
+ if ((a[0] == '/') != (b[0] == '/'))
+ return false;
+
+ for (;;) {
+ size_t j, k;
+
+ a += strspn(a, "/");
+ b += strspn(b, "/");
+
+ if (*a == 0 && *b == 0)
+ return true;
+
+ if (*a == 0 || *b == 0)
+ return false;
+
+ j = strcspn(a, "/");
+ k = strcspn(b, "/");
+
+ if (j != k)
+ return false;
+
+ if (memcmp(a, b, j) != 0)
+ return false;
+
+ a += j;
+ b += k;
+ }
+}
+
+int path_is_mount_point(const char *t, bool allow_symlink) {
+ struct stat a, b;
+ char *parent;
+ int r;
+
+ if (allow_symlink)
+ r = stat(t, &a);
+ else
+ r = lstat(t, &a);
+
+ if (r < 0) {
+ if (errno == ENOENT)
+ return 0;
+
+ return -errno;
+ }
+
+ r = path_get_parent(t, &parent);
+ if (r < 0)
+ return r;
+
+ r = lstat(parent, &b);
+ free(parent);
+
+ if (r < 0)
+ return -errno;
+
+ return a.st_dev != b.st_dev;
+}
+
+int path_is_read_only_fs(const char *path) {
+ struct statvfs st;
+
+ assert(path);
+
+ if (statvfs(path, &st) < 0)
+ return -errno;
+
+ return !!(st.f_flag & ST_RDONLY);
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foopathutilhfoo
+#define foopathutilhfoo
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010-2012 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "stdbool.h"
+
+bool is_path(const char *p);
+char **path_split_and_make_absolute(const char *p);
+char *path_get_file_name(const char *p);
+int path_get_parent(const char *path, char **parent);
+bool path_is_absolute(const char *p);
+char *path_make_absolute(const char *p, const char *prefix);
+char *path_make_absolute_cwd(const char *p);
+int path_parent(const char *path, char **parent);
+char *path_kill_slashes(char *path);
+bool path_startswith(const char *path, const char *prefix);
+bool path_equal(const char *a, const char *b);
+
+char **path_strv_make_absolute_cwd(char **l);
+char **path_strv_canonicalize(char **l);
+char **path_strv_remove_empty(char **l);
+
+int path_is_mount_point(const char *path, bool allow_symlink);
+int path_is_read_only_fs(const char *path);
+
+#endif
#include "macro.h"
#include "util.h"
#include "mkdir.h"
+#include "path-util.h"
#include "socket-util.h"
#include "missing.h"
#include <string.h>
#include <assert.h>
+#include "path-util.h"
#include "util.h"
#include "unit-name.h"
#include <glob.h>
#include <grp.h>
#include <sys/mman.h>
-#include <sys/statvfs.h>
#include "macro.h"
#include "util.h"
#include "log.h"
#include "strv.h"
#include "label.h"
+#include "path-util.h"
#include "exit-status.h"
#include "hashmap.h"
return (char*) current;
}
-char **split_path_and_make_absolute(const char *p) {
- char **l;
- assert(p);
-
- if (!(l = strv_split(p, ":")))
- return NULL;
-
- if (!strv_path_make_absolute_cwd(l)) {
- strv_free(l);
- return NULL;
- }
-
- return l;
-}
-
int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
int r;
FILE *f;
return 0;
}
-int parent_of_path(const char *path, char **_r) {
- const char *e, *a = NULL, *b = NULL, *p;
- char *r;
- bool slash = false;
-
- assert(path);
- assert(_r);
-
- if (!*path)
- return -EINVAL;
-
- for (e = path; *e; e++) {
-
- if (!slash && *e == '/') {
- a = b;
- b = e;
- slash = true;
- } else if (slash && *e != '/')
- slash = false;
- }
-
- if (*(e-1) == '/')
- p = a;
- else
- p = b;
-
- if (!p)
- return -EINVAL;
-
- if (p == path)
- r = strdup("/");
- else
- r = strndup(path, p-path);
-
- if (!r)
- return -ENOMEM;
-
- *_r = r;
- return 0;
-}
-
-
-char *file_name_from_path(const char *p) {
- char *r;
-
- assert(p);
-
- if ((r = strrchr(p, '/')))
- return r + 1;
-
- return (char*) p;
-}
-
-bool path_is_absolute(const char *p) {
- assert(p);
-
- return p[0] == '/';
-}
-
-bool is_path(const char *p) {
-
- return !!strchr(p, '/');
-}
-
-char *path_make_absolute(const char *p, const char *prefix) {
- assert(p);
-
- /* Makes every item in the list an absolute path by prepending
- * the prefix, if specified and necessary */
-
- if (path_is_absolute(p) || !prefix)
- return strdup(p);
-
- return join(prefix, "/", p, NULL);
-}
-
-char *path_make_absolute_cwd(const char *p) {
- char *cwd, *r;
-
- assert(p);
-
- /* Similar to path_make_absolute(), but prefixes with the
- * current working directory. */
-
- if (path_is_absolute(p))
- return strdup(p);
-
- if (!(cwd = get_current_dir_name()))
- return NULL;
-
- r = path_make_absolute(p, cwd);
- free(cwd);
-
- return r;
-}
-
-char **strv_path_make_absolute_cwd(char **l) {
- char **s;
-
- /* Goes through every item in the string list and makes it
- * absolute. This works in place and won't rollback any
- * changes on failure. */
-
- STRV_FOREACH(s, l) {
- char *t;
-
- if (!(t = path_make_absolute_cwd(*s)))
- return NULL;
-
- free(*s);
- *s = t;
- }
-
- return l;
-}
-
-char **strv_path_canonicalize(char **l) {
- char **s;
- unsigned k = 0;
- bool enomem = false;
-
- if (strv_isempty(l))
- return l;
-
- /* Goes through every item in the string list and canonicalize
- * the path. This works in place and won't rollback any
- * changes on failure. */
-
- STRV_FOREACH(s, l) {
- char *t, *u;
-
- t = path_make_absolute_cwd(*s);
- free(*s);
-
- if (!t) {
- enomem = true;
- continue;
- }
-
- errno = 0;
- u = canonicalize_file_name(t);
- free(t);
-
- if (!u) {
- if (errno == ENOMEM || !errno)
- enomem = true;
-
- continue;
- }
-
- l[k++] = u;
- }
-
- l[k] = NULL;
-
- if (enomem)
- return NULL;
-
- return l;
-}
-
-char **strv_path_remove_empty(char **l) {
- char **f, **t;
-
- if (!l)
- return NULL;
-
- for (f = t = l; *f; f++) {
-
- if (dir_is_empty(*f) > 0) {
- free(*f);
- continue;
- }
-
- *(t++) = *f;
- }
-
- *t = NULL;
- return l;
-}
-
int reset_all_signal_handlers(void) {
int sig;
return r;
}
-char *path_kill_slashes(char *path) {
- char *f, *t;
- bool slash = false;
-
- /* Removes redundant inner and trailing slashes. Modifies the
- * passed string in-place.
- *
- * ///foo///bar/ becomes /foo/bar
- */
-
- for (f = path, t = path; *f; f++) {
-
- if (*f == '/') {
- slash = true;
- continue;
- }
-
- if (slash) {
- slash = false;
- *(t++) = '/';
- }
-
- *(t++) = *f;
- }
-
- /* Special rule, if we are talking of the root directory, a
- trailing slash is good */
-
- if (t == path && slash)
- *(t++) = '/';
-
- *t = 0;
- return path;
-}
-
-bool path_startswith(const char *path, const char *prefix) {
- assert(path);
- assert(prefix);
-
- if ((path[0] == '/') != (prefix[0] == '/'))
- return false;
-
- for (;;) {
- size_t a, b;
-
- path += strspn(path, "/");
- prefix += strspn(prefix, "/");
-
- if (*prefix == 0)
- return true;
-
- if (*path == 0)
- return false;
-
- a = strcspn(path, "/");
- b = strcspn(prefix, "/");
-
- if (a != b)
- return false;
-
- if (memcmp(path, prefix, a) != 0)
- return false;
-
- path += a;
- prefix += b;
- }
-}
-
-bool path_equal(const char *a, const char *b) {
- assert(a);
- assert(b);
-
- if ((a[0] == '/') != (b[0] == '/'))
- return false;
-
- for (;;) {
- size_t j, k;
-
- a += strspn(a, "/");
- b += strspn(b, "/");
-
- if (*a == 0 && *b == 0)
- return true;
-
- if (*a == 0 || *b == 0)
- return false;
-
- j = strcspn(a, "/");
- k = strcspn(b, "/");
-
- if (j != k)
- return false;
-
- if (memcmp(a, b, j) != 0)
- return false;
-
- a += j;
- b += k;
- }
-}
-
char *ascii_strlower(char *t) {
char *p;
return n;
}
-int path_is_mount_point(const char *t, bool allow_symlink) {
- struct stat a, b;
- char *parent;
- int r;
-
- if (allow_symlink)
- r = stat(t, &a);
- else
- r = lstat(t, &a);
-
- if (r < 0) {
- if (errno == ENOENT)
- return 0;
-
- return -errno;
- }
-
- r = parent_of_path(t, &parent);
- if (r < 0)
- return r;
-
- r = lstat(parent, &b);
- free(parent);
-
- if (r < 0)
- return -errno;
-
- return a.st_dev != b.st_dev;
-}
-
int parse_usec(const char *t, usec_t *usec) {
static const struct {
const char *suffix;
if (!t)
return -ENOMEM;
- fn = file_name_from_path(path);
+ fn = path_get_file_name(path);
k = fn-path;
memcpy(t, path, k);
t[k] = '.';
assert(from);
assert(to);
- if (parent_of_path(from, &pf) < 0 ||
- parent_of_path(to, &pt) < 0) {
+ if (path_get_parent(from, &pf) < 0 ||
+ path_get_parent(to, &pt) < 0) {
r = -ENOMEM;
goto finish;
}
if (!t)
return -ENOMEM;
- fn = file_name_from_path(to);
+ fn = path_get_file_name(to);
k = fn-to;
memcpy(t, to, k);
t[k] = '.';
char **i, *parent;
int r;
- r = parent_of_path(path, &parent);
+ r = path_get_parent(path, &parent);
if (r < 0)
return r;
return 0;
}
-int path_is_read_only_fs(const char *path) {
- struct statvfs st;
-
- assert(path);
-
- if (statvfs(path, &st) < 0)
- return -errno;
-
- return !!(st.f_flag & ST_RDONLY);
-}
-
int getenv_for_pid(pid_t pid, const char *field, char **_value) {
char path[sizeof("/proc/")-1+10+sizeof("/environ")], *value = NULL;
int r;
return s ? s : "n/a";
}
-static inline bool is_path_absolute(const char *p) {
- return *p == '/';
-}
-
static inline bool isempty(const char *p) {
return !p || !p[0];
}
#define FOREACH_WORD_QUOTED(word, length, s, state) \
for ((state) = NULL, (word) = split_quoted((s), &(length), &(state)); (word); (word) = split_quoted((s), &(length), &(state)))
-char **split_path_and_make_absolute(const char *p);
-
pid_t get_parent_of_pid(pid_t pid, pid_t *ppid);
int get_starttime_of_pid(pid_t pid, unsigned long long *st);
int readlink_and_make_absolute(const char *p, char **r);
int readlink_and_canonicalize(const char *p, char **r);
-char *file_name_from_path(const char *p);
-bool is_path(const char *p);
-
-bool path_is_absolute(const char *p);
-char *path_make_absolute(const char *p, const char *prefix);
-char *path_make_absolute_cwd(const char *p);
-
-char **strv_path_make_absolute_cwd(char **l);
-char **strv_path_canonicalize(char **l);
-char **strv_path_remove_empty(char **l);
-
int reset_all_signal_handlers(void);
char *strstrip(char *s);
char *file_in_same_dir(const char *path, const char *filename);
-int parent_of_path(const char *path, char **parent);
-
int rmdir_parents(const char *path, const char *stop);
int get_process_comm(pid_t pid, char **name);
char *bus_path_escape(const char *s);
char *bus_path_unescape(const char *s);
-char *path_kill_slashes(char *path);
-
-bool path_startswith(const char *path, const char *prefix);
-bool path_equal(const char *a, const char *b);
-
char *ascii_strlower(char *path);
bool dirent_is_file(const struct dirent *de);
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
-int path_is_mount_point(const char *path, bool allow_symlink);
-int path_is_read_only_fs(const char *path);
-
bool is_device_path(const char *path);
int dir_is_empty(const char *path);
#include <sys/poll.h>
#include "macro.h"
+#include "path-util.h"
#include "utmp-wtmp.h"
int utmp_get_runlevel(int *runlevel, int *previous) {
strncpy(store.ut_id, sanitize_id(id), sizeof(store.ut_id));
if (line)
- strncpy(store.ut_line, file_name_from_path(line), sizeof(store.ut_line));
+ strncpy(store.ut_line, path_get_file_name(line), sizeof(store.ut_line));
return write_entry_both(&store);
}
#include "strv.h"
#include "util.h"
#include "strv.h"
+#include "path-util.h"
#include "conf-files.h"
#define PROC_SYS_PREFIX "/proc/sys/"
#include "utmp-wtmp.h"
#include "special.h"
#include "initreq.h"
+#include "path-util.h"
#include "strv.h"
#include "dbus-common.h"
#include "cgroup-show.h"
#include "spawn-polkit-agent.h"
#include "install.h"
#include "logs-show.h"
+#include "path-util.h"
static const char *arg_type = NULL;
static char **arg_property = NULL;
return r;
}
- return strcasecmp(file_name_from_path(u->path), file_name_from_path(v->path));
+ return strcasecmp(path_get_file_name(u->path), path_get_file_name(v->path));
}
static bool output_show_unit_file(const UnitFileList *u) {
if (!output_show_unit_file(u))
continue;
- max_id_len = MAX(max_id_len, strlen(file_name_from_path(u->path)));
+ max_id_len = MAX(max_id_len, strlen(path_get_file_name(u->path)));
state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
}
} else
on = off = "";
- id = file_name_from_path(u->path);
+ id = path_get_file_name(u->path);
e = arg_full ? NULL : ellipsize(id, id_cols, 33);
if (!isempty(arg_root))
argv[c++] = q = strappend("--root=", arg_root);
- argv[c++] = file_name_from_path(p);
+ argv[c++] = path_get_file_name(p);
argv[c++] =
streq(verb, "enable") ? "on" :
streq(verb, "disable") ? "off" : "--level=5";
#include <string.h>
#include "cgroup-util.h"
+#include "path-util.h"
#include "util.h"
#include "log.h"
#include <fcntl.h>
#include "util.h"
+#include "path-util.h"
#include "install.h"
static void dump_changes(UnitFileChange *c, unsigned n) {
HASHMAP_FOREACH(p, h, i) {
UnitFileState s;
- s = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(p->path));
+ s = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(p->path));
assert_se(p->state == s);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files2[0])) == UNIT_FILE_ENABLED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == UNIT_FILE_ENABLED);
log_error("disable files2");
changes = NULL;
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files2[0])) == _UNIT_FILE_STATE_INVALID);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == _UNIT_FILE_STATE_INVALID);
log_error("link files2");
changes = NULL;
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files2[0])) == UNIT_FILE_LINKED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == UNIT_FILE_LINKED);
log_error("disable files2");
changes = NULL;
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files2[0])) == _UNIT_FILE_STATE_INVALID);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == _UNIT_FILE_STATE_INVALID);
log_error("link files2");
changes = NULL;
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files2[0])) == UNIT_FILE_LINKED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == UNIT_FILE_LINKED);
log_error("reenable files2");
changes = NULL;
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files2[0])) == UNIT_FILE_ENABLED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == UNIT_FILE_ENABLED);
log_error("disable files2");
changes = NULL;
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files2[0])) == _UNIT_FILE_STATE_INVALID);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == _UNIT_FILE_STATE_INVALID);
log_error("preset files");
changes = NULL;
n_changes = 0;
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files[0])) == UNIT_FILE_ENABLED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files[0])) == UNIT_FILE_ENABLED);
return 0;
}
#include "log.h"
#include "util.h"
#include "mkdir.h"
+#include "path-util.h"
#include "strv.h"
#include "label.h"
#include "set.h"
#include "util.h"
#include "mkdir.h"
+#include "path-util.h"
#include "conf-parser.h"
#include "utmp-wtmp.h"
#include "socket-util.h"
#include <time.h>
#include "udev.h"
+#include "path-util.h"
#include "conf-files.h"
#define PREALLOC_TOKEN 2048
log_error("failed to build config directory array");
return NULL;
}
- if (!strv_path_canonicalize(rules->dirs)) {
+ if (!path_strv_canonicalize(rules->dirs)) {
log_error("failed to canonicalize config directories\n");
return NULL;
}