* Wrote a test application trying to reproduce bug #2197, ie. modelled after
Mozilla's PR_NewTCPSocketPair() -- unfortunately, it doesn't seem to work. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30304 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
b09fa0e435
commit
59b3d28a25
|
@ -2,6 +2,8 @@ SubDir HAIKU_TOP src tests kits net ;
|
|||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
SimpleTest firefox_crash : firefox_crash.cpp : $(TARGET_NETWORK_LIBS) ;
|
||||
|
||||
SimpleTest udp_client : udp_client.c : $(TARGET_NETWORK_LIBS) ;
|
||||
SimpleTest udp_echo : udp_echo.c : $(TARGET_NETWORK_LIBS) ;
|
||||
SimpleTest udp_server : udp_server.c : $(TARGET_NETWORK_LIBS) ;
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
//! A test app trying to reproduce bug #2197.
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
static int
|
||||
open_tcp_socket()
|
||||
{
|
||||
int fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
// make it non-blocking
|
||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_sockaddr(struct sockaddr_in& address, unsigned ipAddress, unsigned port)
|
||||
{
|
||||
memset(&address, 0, sizeof(sockaddr_in));
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_port = htons(port);
|
||||
address.sin_addr.s_addr = htonl(ipAddress);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
tcp_pair(int pair[])
|
||||
{
|
||||
pair[0] = pair[1] = -1;
|
||||
|
||||
int listenSocket = open_tcp_socket();
|
||||
if (listenSocket < 0)
|
||||
return -1;
|
||||
|
||||
sockaddr_in listenAddress;
|
||||
sockaddr_in peerAddress;
|
||||
sockaddr_in address;
|
||||
socklen_t length;
|
||||
init_sockaddr(listenAddress, INADDR_LOOPBACK, 0);
|
||||
|
||||
if (bind(listenSocket, (sockaddr*)&listenAddress, sizeof(sockaddr_in)) != 0)
|
||||
goto error;
|
||||
|
||||
length = sizeof(sockaddr_in);
|
||||
if (getsockname(listenSocket, (sockaddr*)&listenAddress, &length) != 0)
|
||||
goto error;
|
||||
|
||||
if (listen(listenSocket, 5) != 0)
|
||||
goto error;
|
||||
|
||||
pair[0] = open_tcp_socket();
|
||||
if (pair[0] < 0)
|
||||
goto error;
|
||||
|
||||
init_sockaddr(address, INADDR_LOOPBACK, ntohs(listenAddress.sin_port));
|
||||
|
||||
if (connect(pair[0], (sockaddr*)&address, sizeof(sockaddr_in)) != 0
|
||||
&& errno != EINPROGRESS)
|
||||
goto error;
|
||||
|
||||
if (errno == EINPROGRESS) {
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 100000;
|
||||
tv.tv_usec = 0;
|
||||
fd_set set;
|
||||
FD_ZERO(&set);
|
||||
FD_SET(pair[0], &set);
|
||||
if (select(pair[0] + 1, NULL, &set, NULL, &tv) < 0)
|
||||
fprintf(stderr, "write select() failed: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
length = sizeof(sockaddr_in);
|
||||
if (getsockname(pair[0], (sockaddr*)&address, &length) != 0)
|
||||
goto error;
|
||||
|
||||
while (true) {
|
||||
pair[1] = accept(listenSocket, (sockaddr*)&peerAddress, &length);
|
||||
if (pair[1] >= 0)
|
||||
break;
|
||||
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK && errno != ETIMEDOUT)
|
||||
goto error;
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 100000;
|
||||
tv.tv_usec = 0;
|
||||
fd_set set;
|
||||
FD_ZERO(&set);
|
||||
FD_SET(listenSocket, &set);
|
||||
if (select(listenSocket + 1, &set, NULL, NULL, &tv) < 0)
|
||||
fprintf(stderr, "read select() failed: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
if (peerAddress.sin_port != address.sin_port)
|
||||
goto error;
|
||||
|
||||
close(listenSocket);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
close(listenSocket);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (pair[i] >= 0)
|
||||
close(pair[i]);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
int pair[2];
|
||||
if (tcp_pair(pair) == 0) {
|
||||
close(pair[0]);
|
||||
close(pair[1]);
|
||||
} else
|
||||
fprintf(stderr, "pair failed: %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue