]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fd-util: introduce fd_validate() helper
authorLennart Poettering <lennart@poettering.net>
Tue, 8 Oct 2024 09:51:48 +0000 (11:51 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 8 Oct 2024 11:13:44 +0000 (13:13 +0200)
It just uses F_GETFD to validate an fd. it's a bit easier to read
though, and handles the < 0 case internally.

src/basic/fd-util.c
src/basic/fd-util.h
src/libsystemd/sd-daemon/sd-daemon.c
src/test/test-fd-util.c
src/test/test-fdset.c

index 88b76c51d0baa421ead06706cd2d4032d96a632b..3f8c5b92d32e90359a86df14220b98e4e19df04f 100644 (file)
@@ -511,6 +511,16 @@ int pack_fds(int fds[], size_t n_fds) {
         return 0;
 }
 
+int fd_validate(int fd) {
+        if (fd < 0)
+                return -EBADF;
+
+        if (fcntl(fd, F_GETFD) < 0)
+                return -errno;
+
+        return 0;
+}
+
 int same_fd(int a, int b) {
         struct stat sta, stb;
         pid_t pid;
index 3a56d2cbbf17e02aa45628babf61938a2a7680e3..93b254c6805b35eec263923993ab355e3c3a8d33 100644 (file)
@@ -80,6 +80,7 @@ int close_all_fds_without_malloc(const int except[], size_t n_except);
 
 int pack_fds(int fds[], size_t n);
 
+int fd_validate(int fd);
 int same_fd(int a, int b);
 
 void cmsg_close_all(struct msghdr *mh);
index b5469b5d98bfbf0079eab9b0e0422c3bb0611ce4..1e28a45fde204934aabc993bb2dc13c9c1c516ed 100644 (file)
@@ -400,9 +400,12 @@ _public_ int sd_is_socket_unix(int fd, int type, int listening, const char *path
 
 _public_ int sd_is_mq(int fd, const char *path) {
         struct mq_attr attr;
+        int r;
 
         /* Check that the fd is valid */
-        assert_return(fcntl(fd, F_GETFD) >= 0, -errno);
+        r = fd_validate(fd);
+        if (r < 0)
+                return r;
 
         if (mq_getattr(fd, &attr) < 0) {
                 if (errno == EBADF)
index f2b65d492a63a043589b41bcd1880788823c2b8a..e49a5dde457bf09a8466c3d03f7bd9732941a7e0 100644 (file)
@@ -40,9 +40,9 @@ TEST(close_many) {
 
         close_many(fds, 2);
 
-        assert_se(fcntl(fds[0], F_GETFD) == -1);
-        assert_se(fcntl(fds[1], F_GETFD) == -1);
-        assert_se(fcntl(fds[2], F_GETFD) >= 0);
+        assert_se(fd_validate(fds[0]) == -EBADF);
+        assert_se(fd_validate(fds[1]) == -EBADF);
+        assert_se(fd_validate(fds[2]) >= 0);
 
         safe_close(fds[2]);
 }
@@ -57,6 +57,19 @@ TEST(close_nointr) {
         assert_se(close_nointr(fd) < 0);
 }
 
+TEST(fd_validate) {
+        assert_se(fd_validate(-EINVAL) == -EBADF);
+        assert_se(fd_validate(-EBADF) == -EBADF);
+
+        _cleanup_close_ int b = -EBADF;
+        assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
+
+        assert_se(fd_validate(b) == 0);
+        safe_close(b);
+        assert_se(fd_validate(b) == -EBADF);
+        TAKE_FD(b);
+}
+
 TEST(same_fd) {
         _cleanup_close_pair_ int p[2];
         _cleanup_close_ int a, b, c;
@@ -222,9 +235,9 @@ static size_t validate_fds(
                         continue;
 
                 if (opened)
-                        assert_se(fcntl(fds[i], F_GETFD) >= 0);
+                        assert_se(fd_validate(fds[i]) >= 0);
                 else
-                        assert_se(fcntl(fds[i], F_GETFD) < 0 && errno == EBADF);
+                        assert_se(fd_validate(fds[i]) == -EBADF);
 
                 c++;
         }
index cfbd8e270a8792051fc133e9e065cfda00a0a62a..7aeaf5f129c645cd70cd5a9a9f90a76cbd97792e 100644 (file)
@@ -23,8 +23,7 @@ TEST(fdset_new_fill) {
         assert_se(fdset_new_fill(/* filter_cloexec= */ -1, &fdset) >= 0);
         assert_se(fdset_contains(fdset, fd));
         fdset = fdset_free(fdset);
-        assert_se(fcntl(fd, F_GETFD) < 0);
-        assert_se(errno == EBADF);
+        assert_se(fd_validate(fd) == -EBADF);
 
         fd = open("/dev/null", O_CLOEXEC|O_RDONLY);
         assert_se(fd >= 0);
@@ -32,13 +31,12 @@ TEST(fdset_new_fill) {
         assert_se(fdset_new_fill(/* filter_cloexec= */ 0, &fdset) >= 0);
         assert_se(!fdset_contains(fdset, fd));
         fdset = fdset_free(fdset);
-        assert_se(fcntl(fd, F_GETFD) >= 0);
+        assert_se(fd_validate(fd) >= 0);
 
         assert_se(fdset_new_fill(/* filter_cloexec= */ 1, &fdset) >= 0);
         assert_se(fdset_contains(fdset, fd));
         fdset = fdset_free(fdset);
-        assert_se(fcntl(fd, F_GETFD) < 0);
-        assert_se(errno == EBADF);
+        assert_se(fd_validate(fd) == -EBADF);
 
         fd = open("/dev/null", O_RDONLY);
         assert_se(fd >= 0);
@@ -46,7 +44,7 @@ TEST(fdset_new_fill) {
         assert_se(fdset_new_fill(/* filter_cloexec= */ 1, &fdset) >= 0);
         assert_se(!fdset_contains(fdset, fd));
         fdset = fdset_free(fdset);
-        assert_se(fcntl(fd, F_GETFD) >= 0);
+        assert_se(fd_validate(fd) >= 0);
 
         assert_se(fdset_new_fill(/* filter_cloexec= */ 0, &fdset) >= 0);
         assert_se(fdset_contains(fdset, fd));
@@ -54,8 +52,7 @@ TEST(fdset_new_fill) {
         assert_se(flags >= 0);
         assert_se(FLAGS_SET(flags, FD_CLOEXEC));
         fdset = fdset_free(fdset);
-        assert_se(fcntl(fd, F_GETFD) < 0);
-        assert_se(errno == EBADF);
+        assert_se(fd_validate(fd) == -EBADF);
 
         log_open();
 }
@@ -102,10 +99,8 @@ TEST(fdset_cloexec) {
 }
 
 TEST(fdset_close_others) {
-        int fd = -EBADF;
-        int copyfd = -EBADF;
+        int fd = -EBADF, copyfd = -EBADF;
         _cleanup_fdset_free_ FDSet *fdset = NULL;
-        int flags = -1;
         _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-fdset_close_others.XXXXXX";
 
         fd = mkostemp_safe(name);
@@ -121,15 +116,13 @@ TEST(fdset_close_others) {
         log_close();
         assert_se(fdset_close_others(fdset) >= 0);
 
-        flags = fcntl(fd, F_GETFD);
-        assert_se(flags < 0);
+        assert_se(fd_validate(fd) == -EBADF);
 
         /* Open log again after checking that fd is invalid, since reopening the log might make fd a valid
          * file descriptor again. */
         (void) log_open();
 
-        flags = fcntl(copyfd, F_GETFD);
-        assert_se(flags >= 0);
+        assert_se(fd_validate(copyfd) >= 0);
 }
 
 TEST(fdset_remove) {
@@ -146,7 +139,7 @@ TEST(fdset_remove) {
         assert_se(fdset_remove(fdset, fd) >= 0);
         assert_se(!fdset_contains(fdset, fd));
 
-        assert_se(fcntl(fd, F_GETFD) >= 0);
+        assert_se(fd_validate(fd) >= 0);
 }
 
 TEST(fdset_iterate) {