summaryrefslogtreecommitdiffstats
path: root/src/basic/path-util.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/basic/path-util.c80
1 files changed, 68 insertions, 12 deletions
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
index 6810bf6..068fb42 100644
--- a/src/basic/path-util.c
+++ b/src/basic/path-util.c
@@ -217,8 +217,10 @@ int path_make_relative_parent(const char *from_child, const char *to, char **ret
return path_make_relative(from, to, ret);
}
-char* path_startswith_strv(const char *p, char **set) {
- STRV_FOREACH(s, set) {
+char* path_startswith_strv(const char *p, char * const *strv) {
+ assert(p);
+
+ STRV_FOREACH(s, strv) {
char *t;
t = path_startswith(p, *s);
@@ -525,6 +527,18 @@ int path_compare_filename(const char *a, const char *b) {
return strcmp(fa, fb);
}
+int path_equal_or_inode_same_full(const char *a, const char *b, int flags) {
+ /* Returns true if paths are of the same entry, false if not, <0 on error. */
+
+ if (path_equal(a, b))
+ return 1;
+
+ if (!a || !b)
+ return 0;
+
+ return inode_same(a, b, flags);
+}
+
char* path_extend_internal(char **x, ...) {
size_t sz, old_sz;
char *q, *nx;
@@ -684,7 +698,7 @@ int find_executable_full(
* binary. */
p = getenv("PATH");
if (!p)
- p = DEFAULT_PATH;
+ p = default_PATH();
if (exec_search_path) {
STRV_FOREACH(element, exec_search_path) {
@@ -1094,7 +1108,6 @@ int path_extract_filename(const char *path, char **ret) {
}
int path_extract_directory(const char *path, char **ret) {
- _cleanup_free_ char *a = NULL;
const char *c, *next = NULL;
int r;
@@ -1118,14 +1131,10 @@ int path_extract_directory(const char *path, char **ret) {
if (*path != '/') /* filename only */
return -EDESTADDRREQ;
- a = strdup("/");
- if (!a)
- return -ENOMEM;
- *ret = TAKE_PTR(a);
- return 0;
+ return strdup_to(ret, "/");
}
- a = strndup(path, next - path);
+ _cleanup_free_ char *a = strndup(path, next - path);
if (!a)
return -ENOMEM;
@@ -1336,6 +1345,20 @@ bool dot_or_dot_dot(const char *path) {
return path[2] == 0;
}
+bool path_implies_directory(const char *path) {
+
+ /* Sometimes, if we look at a path we already know it must refer to a directory, because it is
+ * suffixed with a slash, or its last component is "." or ".." */
+
+ if (!path)
+ return false;
+
+ if (dot_or_dot_dot(path))
+ return true;
+
+ return ENDSWITH_SET(path, "/", "/.", "/..");
+}
+
bool empty_or_root(const char *path) {
/* For operations relative to some root directory, returns true if the specified root directory is
@@ -1347,7 +1370,9 @@ bool empty_or_root(const char *path) {
return path_equal(path, "/");
}
-bool path_strv_contains(char **l, const char *path) {
+bool path_strv_contains(char * const *l, const char *path) {
+ assert(path);
+
STRV_FOREACH(i, l)
if (path_equal(*i, path))
return true;
@@ -1355,7 +1380,9 @@ bool path_strv_contains(char **l, const char *path) {
return false;
}
-bool prefixed_path_strv_contains(char **l, const char *path) {
+bool prefixed_path_strv_contains(char * const *l, const char *path) {
+ assert(path);
+
STRV_FOREACH(i, l) {
const char *j = *i;
@@ -1363,6 +1390,7 @@ bool prefixed_path_strv_contains(char **l, const char *path) {
j++;
if (*j == '+')
j++;
+
if (path_equal(j, path))
return true;
}
@@ -1432,3 +1460,31 @@ int path_glob_can_match(const char *pattern, const char *prefix, char **ret) {
*ret = NULL;
return false;
}
+
+const char* default_PATH(void) {
+#if HAVE_SPLIT_BIN
+ static int split = -1;
+ int r;
+
+ /* Check whether /usr/sbin is not a symlink and return the appropriate $PATH.
+ * On error fall back to the safe value with both directories as configured… */
+
+ if (split < 0)
+ STRV_FOREACH_PAIR(bin, sbin, STRV_MAKE("/usr/bin", "/usr/sbin",
+ "/usr/local/bin", "/usr/local/sbin")) {
+ r = inode_same(*bin, *sbin, AT_NO_AUTOMOUNT);
+ if (r > 0 || r == -ENOENT)
+ continue;
+ if (r < 0)
+ log_debug_errno(r, "Failed to compare \"%s\" and \"%s\", using compat $PATH: %m",
+ *bin, *sbin);
+ split = true;
+ break;
+ }
+ if (split < 0)
+ split = false;
+ if (split)
+ return DEFAULT_PATH_WITH_SBIN;
+#endif
+ return DEFAULT_PATH_WITHOUT_SBIN;
+}