swrap: wrap __close_nocancel() if available
[socket_wrapper.git] / tests / test_tcp_dup2.c
1 #include "torture.h"
2
3 #include <cmocka.h>
4 #include <unistd.h>
5 #include <errno.h>
6
7 #ifdef HAVE___CLOSE_NOCANCEL
8 extern int __close_nocancel(int fd);
9 #endif
10
11 static int setup(void **state)
12 {
13         torture_setup_socket_dir(state);
14
15         return 0;
16 }
17
18 static int teardown(void **state)
19 {
20         torture_teardown_socket_dir(state);
21
22         return 0;
23 }
24
25 static void test_dup2_existing_open_fd(void **state)
26 {
27         int s, dup_s;
28         int rc;
29
30         (void) state; /* unused */
31
32         s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
33         assert_int_not_equal(s, -1);
34
35         /*
36          * Here we try to duplicate the existing socket fd to itself
37          * and as per man page for dup2() it must return the already
38          * open fd without any failure.
39          */
40         dup_s = dup2(s, s);
41         assert_int_equal(dup_s, s);
42
43 #ifdef HAVE___CLOSE_NOCANCEL
44         rc = __close_nocancel(s);
45         assert_return_code(rc, errno);
46         rc = close(s);
47         assert_int_equal(rc, -1);
48         assert_int_equal(errno, EBADF);
49         rc = __close_nocancel(s);
50         assert_int_equal(rc, -1);
51         assert_int_equal(errno, EBADF);
52 #else
53         rc = close(s);
54         assert_return_code(rc, errno);
55 #endif
56 }
57
58 int main(void) {
59         int rc;
60
61         const struct CMUnitTest tcp_dup2_tests[] = {
62                 cmocka_unit_test(test_dup2_existing_open_fd),
63         };
64
65         rc = cmocka_run_group_tests(tcp_dup2_tests, setup, teardown);
66
67         return rc;
68 }