]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/basic/fs-util.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / basic / fs-util.c
index fdedeffb9aaabf09dc0583b3b18cae3b6e922713..1eaf820afb45a636a16ce76c7522fcff19ceb8ac 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -104,7 +105,6 @@ int rmdir_parents(const char *path, const char *stop) {
         return 0;
 }
 
-
 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
         struct stat buf;
         int ret;
@@ -324,7 +324,7 @@ int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gi
                 mkdir_parents(path, 0755);
 
         fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY,
-                        (mode == 0 || mode == MODE_INVALID) ? 0644 : mode);
+                  IN_SET(mode, 0, MODE_INVALID) ? 0644 : mode);
         if (fd < 0)
                 return -errno;
 
@@ -359,22 +359,25 @@ int touch(const char *path) {
 }
 
 int symlink_idempotent(const char *from, const char *to) {
-        _cleanup_free_ char *p = NULL;
         int r;
 
         assert(from);
         assert(to);
 
         if (symlink(from, to) < 0) {
+                _cleanup_free_ char *p = NULL;
+
                 if (errno != EEXIST)
                         return -errno;
 
                 r = readlink_malloc(to, &p);
-                if (r < 0)
+                if (r == -EINVAL) /* Not a symlink? In that case return the original error we encountered: -EEXIST */
+                        return -EEXIST;
+                if (r < 0) /* Any other error? In that case propagate it as is */
                         return r;
 
-                if (!streq(p, from))
-                        return -EINVAL;
+                if (!streq(p, from)) /* Not the symlink we want it to be? In that case, propagate the original -EEXIST */
+                        return -EEXIST;
         }
 
         return 0;
@@ -763,12 +766,11 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
                                                 return -ENOMEM;
                                 }
 
-                        }
-
-                        /* Prefix what's left to do with what we just read, and start the loop again,
-                         * but remain in the current directory. */
-
-                        joined = strjoin("/", destination, todo);
+                                /* Prefix what's left to do with what we just read, and start the loop again, but
+                                 * remain in the current directory. */
+                                joined = strjoin(destination, todo);
+                        } else
+                                joined = strjoin("/", destination, todo);
                         if (!joined)
                                 return -ENOMEM;
 
@@ -807,3 +809,18 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
 
         return exists;
 }
+
+int access_fd(int fd, int mode) {
+        char p[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
+        int r;
+
+        /* Like access() but operates on an already open fd */
+
+        xsprintf(p, "/proc/self/fd/%i", fd);
+
+        r = access(p, mode);
+        if (r < 0)
+                r = -errno;
+
+        return r;
+}