The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=63503cbe5a480d1f55fc45ba7a2661ba41c2321f

commit 63503cbe5a480d1f55fc45ba7a2661ba41c2321f
Author:     Ricardo Branco <rbra...@suse.de>
AuthorDate: 2025-06-03 23:07:17 +0000
Commit:     Mark Johnston <ma...@freebsd.org>
CommitDate: 2025-07-06 23:08:46 +0000

    tests: Adapt existing tests for O_CLOEXEC to O_CLOFORK
    
    MFC after:      1 month
    Pull Request:   https://github.com/freebsd/freebsd-src/pull/1698
---
 tests/sys/file/closefrom_test.c   | 35 +++++++++++++-
 tests/sys/file/dup_test.c         | 98 ++++++++++++++++++++++++++++++++++++++-
 tests/sys/kern/unix_passfd_test.c | 25 ++++++++++
 3 files changed, 156 insertions(+), 2 deletions(-)

diff --git a/tests/sys/file/closefrom_test.c b/tests/sys/file/closefrom_test.c
index e30c5eb3d591..7dccf858c772 100644
--- a/tests/sys/file/closefrom_test.c
+++ b/tests/sys/file/closefrom_test.c
@@ -144,7 +144,7 @@ main(void)
        pid_t pid;
        int fd, flags, i, start;
 
-       printf("1..21\n");
+       printf("1..22\n");
 
        /* We'd better start up with fd's 0, 1, and 2 open. */
        start = devnull();
@@ -356,5 +356,38 @@ main(void)
                fail_err("close_range");
        ok("close_range(..., CLOSE_RANGE_CLOEXEC)");
 
+       /* test CLOSE_RANGE_CLOFORK */
+       for (i = 0; i < 8; i++)
+               (void)devnull();
+       fd = highest_fd();
+       start = fd - 8;
+       if (close_range(start + 1, start + 4, CLOSE_RANGE_CLOFORK) < 0)
+               fail_err("close_range(..., CLOSE_RANGE_CLOFORK)");
+       flags = fcntl(start, F_GETFD);
+       if (flags < 0)
+               fail_err("fcntl(.., F_GETFD)");
+       if ((flags & FD_CLOFORK) != 0)
+               fail("close_range", "CLOSE_RANGE_CLOFORK set close-on-exec "
+                   "when it should not have on fd %d", start);
+       for (i = start + 1; i <= start + 4; i++) {
+               flags = fcntl(i, F_GETFD);
+               if (flags < 0)
+                       fail_err("fcntl(.., F_GETFD)");
+               if ((flags & FD_CLOFORK) == 0)
+                       fail("close_range", "CLOSE_RANGE_CLOFORK did not set "
+                           "close-on-exec on fd %d", i);
+       }
+       for (; i < start + 8; i++) {
+               flags = fcntl(i, F_GETFD);
+               if (flags < 0)
+                       fail_err("fcntl(.., F_GETFD)");
+               if ((flags & FD_CLOFORK) != 0)
+                       fail("close_range", "CLOSE_RANGE_CLOFORK set 
close-on-exec "
+                           "when it should not have on fd %d", i);
+       }
+       if (close_range(start, start + 8, 0) < 0)
+               fail_err("close_range");
+       ok("close_range(..., CLOSE_RANGE_CLOFORK)");
+
        return (0);
 }
diff --git a/tests/sys/file/dup_test.c b/tests/sys/file/dup_test.c
index b024e72d0d1a..455115eda8c8 100644
--- a/tests/sys/file/dup_test.c
+++ b/tests/sys/file/dup_test.c
@@ -46,6 +46,8 @@
  * Test #31: check if dup3(0) fails if oldfd == newfd.
  * Test #32: check if dup3(O_CLOEXEC) to a fd > current maximum number of
  *           open files limit work.
+ * Tests #33-43 : Same as #18-26, 30 & 32 with O_CLOFORK instead of O_CLOEXEC,
+ *           except F_DUP2FD_CLOEXEC.
  */
 
 #include <sys/types.h>
@@ -82,7 +84,7 @@ main(int __unused argc, char __unused *argv[])
 
        orgfd = getafile();
 
-       printf("1..32\n");
+       printf("1..43\n");
 
        /* If dup(2) ever work? */
        if ((fd1 = dup(orgfd)) < 0)
@@ -380,5 +382,99 @@ main(int __unused argc, char __unused *argv[])
                printf("ok %d - dup3(O_CLOEXEC) didn't bypass NOFILE limit\n",
                    test);
 
+       /* Does fcntl(F_DUPFD_CLOFORK) work? */
+       if ((fd2 = fcntl(fd1, F_DUPFD_CLOFORK, 10)) < 0)
+               err(1, "fcntl(F_DUPFD_CLOFORK)");
+       if (fd2 < 10)
+               printf("not ok %d - fcntl(F_DUPFD_CLOFORK) returned wrong fd 
%d\n",
+                   ++test, fd2);
+       else
+               printf("ok %d - fcntl(F_DUPFD_CLOFORK) works\n", ++test);
+
+       /* Was close-on-fork cleared? */
+       ++test;
+        if (fcntl(fd2, F_GETFD) != FD_CLOFORK)
+               printf(
+                   "not ok %d - fcntl(F_DUPFD_CLOFORK) didn't set 
close-on-fork\n",
+                   test);
+       else
+               printf("ok %d - fcntl(F_DUPFD_CLOFORK) set close-on-fork\n",
+                   test);
+
+       /* Does dup3(O_CLOFORK) ever work? */
+       if ((fd2 = dup3(fd1, fd1 + 1, O_CLOFORK)) < 0)
+               err(1, "dup3(O_CLOFORK)");
+       printf("ok %d - dup3(O_CLOFORK) works\n", ++test);
+
+       /* Do we get the right fd? */
+       ++test;
+       if (fd2 != fd1 + 1)
+               printf(
+                   "no ok %d - dup3(O_CLOFORK) didn't give us the right fd\n",
+                   test);
+       else
+               printf("ok %d - dup3(O_CLOFORK) returned a correct fd\n",
+                   test);
+
+       /* Was close-on-fork set? */
+       ++test;
+       if (fcntl(fd2, F_GETFD) != FD_CLOFORK)
+               printf(
+                   "not ok %d - dup3(O_CLOFORK) didn't set close-on-fork\n",
+                   test);
+       else
+               printf("ok %d - dup3(O_CLOFORK) set close-on-fork\n",
+                   test);
+
+       /* Does dup3(0) ever work? */
+       if ((fd2 = dup3(fd1, fd1 + 1, 0)) < 0)
+               err(1, "dup3(0)");
+       printf("ok %d - dup3(0) works\n", ++test);
+
+       /* Do we get the right fd? */
+       ++test;
+       if (fd2 != fd1 + 1)
+               printf(
+                   "no ok %d - dup3(0) didn't give us the right fd\n",
+                   test);
+       else
+               printf("ok %d - dup3(0) returned a correct fd\n",
+                   test);
+
+       /* Was close-on-fork cleared? */
+       ++test;
+       if (fcntl(fd2, F_GETFD) != 0)
+               printf(
+                   "not ok %d - dup3(0) didn't clear close-on-fork\n",
+                   test);
+       else
+               printf("ok %d - dup3(0) cleared close-on-fork\n",
+                   test);
+
+       /* dup3() does not allow duplicating to the same fd */
+       ++test;
+       if (dup3(fd1, fd1, O_CLOFORK) != -1)
+               printf(
+                   "not ok %d - dup3(fd1, fd1, O_CLOFORK) succeeded\n", test);
+       else
+               printf("ok %d - dup3(fd1, fd1, O_CLOFORK) failed\n", test);
+
+       ++test;
+       if (dup3(fd1, fd1, 0) != -1)
+               printf(
+                   "not ok %d - dup3(fd1, fd1, 0) succeeded\n", test);
+       else
+               printf("ok %d - dup3(fd1, fd1, 0) failed\n", test);
+
+       ++test;
+       if (getrlimit(RLIMIT_NOFILE, &rlp) < 0)
+               err(1, "getrlimit");
+       if ((fd2 = dup3(fd1, rlp.rlim_cur + 1, O_CLOFORK)) >= 0)
+               printf("not ok %d - dup3(O_CLOFORK) bypassed NOFILE limit\n",
+                   test);
+       else
+               printf("ok %d - dup3(O_CLOFORK) didn't bypass NOFILE limit\n",
+                   test);
+
        return (0);
 }
diff --git a/tests/sys/kern/unix_passfd_test.c 
b/tests/sys/kern/unix_passfd_test.c
index 95271c04a16b..7dc4541ad402 100644
--- a/tests/sys/kern/unix_passfd_test.c
+++ b/tests/sys/kern/unix_passfd_test.c
@@ -379,6 +379,30 @@ ATF_TC_BODY(simple_send_fd_msg_cmsg_cloexec, tc)
        closesocketpair(fd);
 }
 
+/*
+ * Like simple_send_fd but also sets MSG_CMSG_CLOFORK and checks that the
+ * received file descriptor has the FD_CLOFORK flag set.
+ */
+ATF_TC_WITHOUT_HEAD(simple_send_fd_msg_cmsg_clofork);
+ATF_TC_BODY(simple_send_fd_msg_cmsg_clofork, tc)
+{
+       struct stat getfd_stat, putfd_stat;
+       int fd[2], getfd, putfd;
+
+       domainsocketpair(fd);
+       tempfile(&putfd);
+       dofstat(putfd, &putfd_stat);
+       sendfd(fd[0], putfd);
+       recvfd(fd[1], &getfd, MSG_CMSG_CLOFORK);
+       dofstat(getfd, &getfd_stat);
+       samefile(&putfd_stat, &getfd_stat);
+       ATF_REQUIRE_EQ_MSG(fcntl(getfd, F_GETFD) & FD_CLOFORK, FD_CLOFORK,
+           "FD_CLOFORK not set on the received file descriptor");
+       close(putfd);
+       close(getfd);
+       closesocketpair(fd);
+}
+
 /*
  * Same as simple_send_fd, only close the file reference after sending, so that
  * the only reference is the descriptor in the UNIX domain socket buffer.
@@ -1170,6 +1194,7 @@ ATF_TP_ADD_TCS(tp)
 
        ATF_TP_ADD_TC(tp, simple_send_fd);
        ATF_TP_ADD_TC(tp, simple_send_fd_msg_cmsg_cloexec);
+       ATF_TP_ADD_TC(tp, simple_send_fd_msg_cmsg_clofork);
        ATF_TP_ADD_TC(tp, send_and_close);
        ATF_TP_ADD_TC(tp, send_and_cancel);
        ATF_TP_ADD_TC(tp, send_and_shutdown);

Reply via email to