1 #include <darwintest.h>
2 #include <darwintest_utils.h>
4 #include <sys/select.h>
5 #include <sys/fileport.h>
10 T_META_RUN_CONCURRENTLY(true),
11 T_META_LTEPHASE(LTE_POSTINIT
)
15 fd_select_close_helper(void *ctx
)
19 // wait for the thread to enter select
26 T_DECL(fd_select_close
, "Test for 54795873: make sure close breaks out of select")
32 rc
= socketpair(PF_LOCAL
, SOCK_STREAM
, 0, pair
);
33 T_ASSERT_POSIX_SUCCESS(rc
, "socketpair");
35 pthread_create(&th
, NULL
, fd_select_close_helper
, pair
);
38 FD_SET(pair
[0], &read_fd
);
40 rc
= select(pair
[0] + 1, &read_fd
, NULL
, NULL
, NULL
);
41 T_EXPECT_POSIX_FAILURE(rc
, EBADF
, "select broke out with EBADF");
45 fd_stress_dup2_close_fun(void *ctx
)
47 int thno
= (int)(long)ctx
;
48 int count
= 10000, rc
;
50 for (int i
= 1; i
<= count
; i
++) {
51 rc
= dup2(STDIN_FILENO
, 42);
52 T_QUIET
; T_EXPECT_POSIX_SUCCESS(rc
, "dup2(%d, 42)", STDIN_FILENO
);
56 T_QUIET
; T_EXPECT_POSIX_FAILURE(rc
, EBADF
, "close(42)");
60 T_LOG("thread %d: %d/%d dups\n", thno
, i
, count
);
67 T_DECL(fd_stress_dup2_close
, "Stress test races between dup2 and close")
72 for (int i
= 0; i
< 4; i
++) {
73 rc
= pthread_create(&th
[i
], NULL
,
74 fd_stress_dup2_close_fun
, (void *)(long)i
);
75 T_ASSERT_POSIX_ZERO(rc
, "pthread_create");
78 for (int i
= 0; i
< 4; i
++) {
79 pthread_join(th
[i
], NULL
);
83 T_DECL(fd_dup2_erase_clofork_58446996
,
84 "Make sure dup2() doesn't inherit flags from an old fd")
88 fd1
= open("/dev/null", O_RDONLY
| O_CLOEXEC
);
89 T_ASSERT_POSIX_SUCCESS(fd1
, "open(/dev/null)");
91 fd2
= open("/dev/null", O_RDONLY
| O_CLOEXEC
);
92 T_ASSERT_POSIX_SUCCESS(fd2
, "open(/dev/null)");
94 T_ASSERT_POSIX_SUCCESS(dup2(fd1
, fd2
), "dup2(fd1, fd2)");
95 T_EXPECT_EQ(fcntl(fd2
, F_GETFD
, 0), 0,
96 "neither FD_CLOEXEC nor FD_CLOFORK should be set");
99 struct confined_race_state
{
105 confine_thread(void *data
)
107 volatile int *fdp
= data
;
110 fcntl(*fdp
, F_SETCONFINED
, 1);
116 T_DECL(confined_fileport_race
, "test for rdar://69922255")
120 mach_port_t p
= MACH_PORT_NULL
;
122 T_ASSERT_POSIX_SUCCESS(pthread_create(&t
, NULL
, confine_thread
, &fd
),
125 for (int i
= 0; i
< 100 * 1000; i
++) {
126 fd
= open("/dev/null", O_RDONLY
| 0x08000000 /* O_CLOFORK */);
127 T_QUIET
; T_ASSERT_POSIX_SUCCESS(fd
, "open(/dev/null)");
128 if (fileport_makeport(fd
, &p
) == 0) {
129 T_QUIET
; T_ASSERT_EQ(fcntl(fd
, F_GETCONFINED
), 0,
130 "should never get a confined fd: %d", fd
);
131 mach_port_destroy(mach_task_self(), p
);