1 /* Test the accept4 function with differing flags arguments.
2 Copyright (C) 2017-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 #include <arpa/inet.h>
23 #include <support/check.h>
24 #include <support/xsocket.h>
25 #include <support/xunistd.h>
26 #include <sys/socket.h>
29 is_nonblocking (int fd
)
31 int status
= fcntl (fd
, F_GETFL
);
33 FAIL_EXIT1 ("fcntl (F_GETFL): %m");
34 return status
& O_NONBLOCK
;
40 int status
= fcntl (fd
, F_GETFD
);
42 FAIL_EXIT1 ("fcntl (F_GETFD): %m");
43 return status
& FD_CLOEXEC
;
49 struct sockaddr_in address
;
52 /* Perform a non-blocking connect to *SERVER_ADDRESS. */
54 client_connect (const struct sockaddr_in
*server_address
)
57 result
.socket
= xsocket (AF_INET
,
58 SOCK_STREAM
| SOCK_NONBLOCK
| SOCK_CLOEXEC
, 0);
59 TEST_VERIFY (is_nonblocking (result
.socket
));
60 TEST_VERIFY (is_cloexec (result
.socket
));
61 int ret
= connect (result
.socket
, (const struct sockaddr
*) server_address
,
62 sizeof (*server_address
));
63 if (ret
< 0 && errno
!= EINPROGRESS
)
64 FAIL_EXIT1 ("client connect: %m");
65 socklen_t sa_len
= sizeof (result
.address
);
66 xgetsockname (result
.socket
, (struct sockaddr
*) &result
.address
,
68 TEST_VERIFY (sa_len
== sizeof (result
.address
));
73 check_same_address (const struct sockaddr_in
*left
,
74 const struct sockaddr_in
*right
)
76 TEST_VERIFY (left
->sin_family
== AF_INET
);
77 TEST_VERIFY (right
->sin_family
== AF_INET
);
78 TEST_VERIFY (left
->sin_addr
.s_addr
== right
->sin_addr
.s_addr
);
79 TEST_VERIFY (left
->sin_port
== right
->sin_port
);
85 /* Create server socket. */
86 int server_socket
= xsocket (AF_INET
, SOCK_STREAM
, 0);
87 TEST_VERIFY (!is_nonblocking (server_socket
));
88 TEST_VERIFY (!is_cloexec (server_socket
));
89 struct sockaddr_in server_address
=
91 .sin_family
= AF_INET
,
92 .sin_addr
= {.s_addr
= htonl (INADDR_LOOPBACK
) },
95 (struct sockaddr
*) &server_address
, sizeof (server_address
));
97 socklen_t sa_len
= sizeof (server_address
);
98 xgetsockname (server_socket
, (struct sockaddr
*) &server_address
,
100 TEST_VERIFY (sa_len
== sizeof (server_address
));
102 xlisten (server_socket
, 5);
104 for (int do_nonblock
= 0; do_nonblock
< 2; ++do_nonblock
)
105 for (int do_cloexec
= 0; do_cloexec
< 2; ++do_cloexec
)
109 sockflags
|= SOCK_NONBLOCK
;
111 sockflags
|= SOCK_CLOEXEC
;
113 struct client client
= client_connect (&server_address
);
114 struct sockaddr_in client_address
;
115 socklen_t sa_len
= sizeof (client_address
);
116 int client_socket
= xaccept4 (server_socket
,
117 (struct sockaddr
*) &client_address
,
119 TEST_VERIFY (sa_len
== sizeof (client_address
));
120 TEST_VERIFY (is_nonblocking (client_socket
) == do_nonblock
);
121 TEST_VERIFY (is_cloexec (client_socket
) == do_cloexec
);
122 check_same_address (&client
.address
, &client_address
);
123 xclose (client_socket
);
124 xclose (client
.socket
);
127 xclose (server_socket
);
131 #include <support/test-driver.c>