]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
stat-util: introduce {stat,fd}_verify_linked()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 15 Feb 2024 10:16:36 +0000 (19:16 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 15 Feb 2024 18:48:18 +0000 (03:48 +0900)
src/basic/stat-util.c
src/basic/stat-util.h
src/test/test-stat-util.c

index b42af71ce10e0d9c7e076d403da1acfe9c3956d2..6a8ec1ba2a79d329bc0827833dfda730026ae464 100644 (file)
@@ -260,6 +260,26 @@ int path_is_network_fs(const char *path) {
         return is_network_fs(&s);
 }
 
+int stat_verify_linked(const struct stat *st) {
+        assert(st);
+
+        if (st->st_nlink <= 0)
+                return -EIDRM; /* recognizable error. */
+
+        return 0;
+}
+
+int fd_verify_linked(int fd) {
+        struct stat st;
+
+        assert(fd >= 0);
+
+        if (fstat(fd, &st) < 0)
+                return -errno;
+
+        return stat_verify_linked(&st);
+}
+
 int stat_verify_regular(const struct stat *st) {
         assert(st);
 
index dc11a85f6265324ab42baf9991a4574d86b46cff..bab541535728ac4544ae2709ba09e522c2625e58 100644 (file)
@@ -72,6 +72,9 @@ int path_is_network_fs(const char *path);
  */
 #define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
 
+int stat_verify_linked(const struct stat *st);
+int fd_verify_linked(int fd);
+
 int stat_verify_regular(const struct stat *st);
 int fd_verify_regular(int fd);
 int verify_regular_at(int dir_fd, const char *path, bool follow);
index 3fc83fc043f21ad7cad0ac985caf50d2899eba04..272cd4c0d346f82735af5e7d65207c5f22849e5a 100644 (file)
@@ -195,6 +195,25 @@ TEST(inode_type_from_string) {
                 assert_se(inode_type_from_string(inode_type_to_string(*m)) == *m);
 }
 
+TEST(fd_verify_linked) {
+        _cleanup_(rm_rf_physical_and_freep) char *t = NULL;
+        _cleanup_close_ int tfd = -EBADF, fd = -EBADF;
+        _cleanup_free_ char *p = NULL;
+
+        tfd = mkdtemp_open(NULL, O_PATH, &t);
+        assert_se(tfd >= 0);
+
+        assert_se(p = path_join(t, "hoge"));
+        assert_se(touch(p) >= 0);
+
+        fd = open(p, O_CLOEXEC | O_PATH);
+        assert_se(fd >= 0);
+
+        assert_se(fd_verify_linked(fd) >= 0);
+        assert_se(unlinkat(tfd, "hoge", 0) >= 0);
+        assert_se(fd_verify_linked(fd) == -EIDRM);
+}
+
 static int intro(void) {
         log_show_color(true);
         return EXIT_SUCCESS;