1 /* Test the connect function.
2 Copyright (C) 2024 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>
24 #include <support/check.h>
25 #include <support/xsocket.h>
26 #include <support/xunistd.h>
27 #include <sys/socket.h>
30 static struct sockaddr_in server_address
;
33 open_socket_inet_tcp (void)
35 int fd
= socket (AF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
38 if (errno
== EAFNOSUPPORT
)
39 FAIL_UNSUPPORTED ("The host does not support IPv4");
41 FAIL_EXIT1 ("socket (AF_INET, SOCK_STREAM, IPPROTO_TCP): %m\n");
49 server_address
.sin_family
= AF_INET
;
50 server_address
.sin_port
= 0;
51 server_address
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
53 int server_sock
= open_socket_inet_tcp ();
55 xbind (server_sock
, (struct sockaddr
*) &server_address
,
56 sizeof (server_address
));
58 socklen_t sa_len
= sizeof (server_address
);
59 xgetsockname (server_sock
, (struct sockaddr
*) &server_address
, &sa_len
);
60 xlisten (server_sock
, 5);
62 pid_t my_pid
= xfork ();
69 struct sockaddr_in client_address
;
70 socklen_t ca_len
= sizeof (server_address
);
71 int client_sock
= xaccept (server_sock
, (struct sockaddr
*) &client_address
,
73 printf ("socket accepted %d\n", client_sock
);
82 struct sockaddr_in peer
;
85 serv_pid
= start_server ();
86 int client_sock
= open_socket_inet_tcp ();
87 xconnect (client_sock
, (const struct sockaddr
*) &server_address
,
88 sizeof (server_address
));
90 /* A second connect with same arguments should fail with EISCONN. */
91 int result
= connect (client_sock
,
92 (const struct sockaddr
*) &server_address
,
93 sizeof (server_address
));
94 if (result
== 0 || errno
!= EISCONN
)
95 FAIL_EXIT1 ("Second connect (%d), should fail with EISCONN: %m",
98 peer_len
= sizeof (peer
);
99 xgetpeername (client_sock
, (struct sockaddr
*) &peer
, &peer_len
);
100 TEST_COMPARE (peer_len
, sizeof (peer
));
101 TEST_COMPARE (peer
.sin_port
, server_address
.sin_port
);
102 TEST_COMPARE_BLOB (&peer
.sin_addr
, sizeof (peer
.sin_addr
),
103 &server_address
.sin_addr
,
104 sizeof (server_address
.sin_addr
));
107 xwaitpid (serv_pid
, &status
, 0);
108 TEST_COMPARE (status
, 0);
113 #include <support/test-driver.c>