libs-base/config/config.reuseaddr.c
Richard Frith-MacDonald 01377d55ee socket fixes
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@39919 72102866-910b-0410-8b05-ffd578937521
2016-06-25 15:57:06 +00:00

106 lines
2.3 KiB
C

/*
Copyright (C) 2005 Free Software Foundation
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.
*/
#if defined(__MINGW32__) || defined(__MINGW64__)
#include <windows.h>
#include <winsock2.h>
#else
#include <time.h>
#include <sys/time.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#endif /* __MINGW__ */
#include <sys/file.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#ifndef INADDR_NONE
#define INADDR_NONE -1
#endif
// Maximum data in single I/O operation
#define NETBUF_SIZE 4096
main()
{
struct sockaddr_in sin;
int size = sizeof(sin);
int status = 1;
int port;
int net;
memset(&sin, '\0', sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = 0;
if ((net = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0)
{
fprintf(stderr, "unable to create socket 1\n");
return 2;
}
if (setsockopt(net, SOL_SOCKET, SO_REUSEADDR,
(char *)&status, sizeof(status)) < 0)
{
fprintf(stderr, "unable to set socket 1 option\n");
(void) close(net);
return 1;
}
if (bind(net, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
fprintf(stderr, "unable to bind socket 1\n");
(void) close(net);
return 2;
}
listen(net, 5);
if (getsockname(net, (struct sockaddr*)&sin, &size) < 0)
{
fprintf(stderr, "unable to get socket 1 name\n");
(void) close(net);
return 2;
}
port = sin.sin_port;
memset(&sin, '\0', sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = port;
if ((net = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0)
{
fprintf(stderr, "unable to create socket 2\n");
return 2;
}
if (setsockopt(net, SOL_SOCKET, SO_REUSEADDR,
(char *)&status, sizeof(status)) < 0)
{
fprintf(stderr, "unable to set socket 2 option\n");
(void) close(net);
return 1;
}
/*
* Now ... this bind should fail unless SO_REUSEADDR is broken.
*/
if (bind(net, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
return 0;
}
return 1;
}