edb28b33f3
git-svn-id: svn://kolibrios.org@3770 a494cfbc-eb01-0410-851d-a64ba20cac60
192 lines
3.5 KiB
C
192 lines
3.5 KiB
C
|
|
#include "pipe/p_compiler.h"
|
|
#include "util/u_network.h"
|
|
#include "util/u_debug.h"
|
|
|
|
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
|
|
# include <winsock2.h>
|
|
# include <windows.h>
|
|
#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || \
|
|
defined(PIPE_OS_APPLE) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_SOLARIS)
|
|
# include <sys/socket.h>
|
|
# include <netinet/in.h>
|
|
# include <unistd.h>
|
|
# include <fcntl.h>
|
|
# include <netdb.h>
|
|
#else
|
|
# warning "No socket implementation"
|
|
#endif
|
|
|
|
boolean
|
|
u_socket_init()
|
|
{
|
|
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
|
|
WORD wVersionRequested;
|
|
WSADATA wsaData;
|
|
int err;
|
|
|
|
/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
|
|
wVersionRequested = MAKEWORD(1, 1);
|
|
|
|
err = WSAStartup(wVersionRequested, &wsaData);
|
|
if (err != 0) {
|
|
debug_printf("WSAStartup failed with error: %d\n", err);
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
#elif defined(PIPE_HAVE_SOCKETS)
|
|
return TRUE;
|
|
#else
|
|
return FALSE;
|
|
#endif
|
|
}
|
|
|
|
void
|
|
u_socket_stop()
|
|
{
|
|
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
|
|
WSACleanup();
|
|
#endif
|
|
}
|
|
|
|
void
|
|
u_socket_close(int s)
|
|
{
|
|
if (s < 0)
|
|
return;
|
|
|
|
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) \
|
|
|| defined(PIPE_OS_APPLE) || defined(PIPE_OS_SOLARIS)
|
|
shutdown(s, SHUT_RDWR);
|
|
close(s);
|
|
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
|
|
shutdown(s, SD_BOTH);
|
|
closesocket(s);
|
|
#else
|
|
assert(0);
|
|
#endif
|
|
}
|
|
|
|
int u_socket_accept(int s)
|
|
{
|
|
#if defined(PIPE_HAVE_SOCKETS)
|
|
return accept(s, NULL, NULL);
|
|
#else
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int
|
|
u_socket_send(int s, void *data, size_t size)
|
|
{
|
|
#if defined(PIPE_HAVE_SOCKETS)
|
|
return send(s, data, size, 0);
|
|
#else
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int
|
|
u_socket_peek(int s, void *data, size_t size)
|
|
{
|
|
#if defined(PIPE_HAVE_SOCKETS)
|
|
return recv(s, data, size, MSG_PEEK);
|
|
#else
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int
|
|
u_socket_recv(int s, void *data, size_t size)
|
|
{
|
|
#if defined(PIPE_HAVE_SOCKETS)
|
|
return recv(s, data, size, 0);
|
|
#else
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int
|
|
u_socket_connect(const char *hostname, uint16_t port)
|
|
{
|
|
#if defined(PIPE_HAVE_SOCKETS)
|
|
int s;
|
|
struct sockaddr_in sa;
|
|
struct hostent *host = NULL;
|
|
|
|
memset(&sa, 0, sizeof(struct sockaddr_in));
|
|
host = gethostbyname(hostname);
|
|
if (!host)
|
|
return -1;
|
|
|
|
memcpy((char *)&sa.sin_addr,host->h_addr_list[0],host->h_length);
|
|
sa.sin_family= host->h_addrtype;
|
|
sa.sin_port = htons(port);
|
|
|
|
s = socket(host->h_addrtype, SOCK_STREAM, IPPROTO_TCP);
|
|
if (s < 0)
|
|
return -1;
|
|
|
|
if (connect(s, (struct sockaddr *)&sa, sizeof(sa))) {
|
|
u_socket_close(s);
|
|
return -1;
|
|
}
|
|
|
|
return s;
|
|
#else
|
|
assert(0);
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
int
|
|
u_socket_listen_on_port(uint16_t portnum)
|
|
{
|
|
#if defined(PIPE_HAVE_SOCKETS)
|
|
int s;
|
|
struct sockaddr_in sa;
|
|
memset(&sa, 0, sizeof(struct sockaddr_in));
|
|
|
|
sa.sin_family = AF_INET;
|
|
sa.sin_port = htons(portnum);
|
|
|
|
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
if (s < 0)
|
|
return -1;
|
|
|
|
if (bind(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) == -1) {
|
|
u_socket_close(s);
|
|
return -1;
|
|
}
|
|
|
|
listen(s, 0);
|
|
|
|
return s;
|
|
#else
|
|
assert(0);
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
void
|
|
u_socket_block(int s, boolean block)
|
|
{
|
|
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) \
|
|
|| defined(PIPE_OS_APPLE) || defined(PIPE_OS_SOLARIS)
|
|
int old = fcntl(s, F_GETFL, 0);
|
|
if (old == -1)
|
|
return;
|
|
|
|
/* TODO obey block */
|
|
if (block)
|
|
fcntl(s, F_SETFL, old & ~O_NONBLOCK);
|
|
else
|
|
fcntl(s, F_SETFL, old | O_NONBLOCK);
|
|
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
|
|
u_long iMode = block ? 0 : 1;
|
|
ioctlsocket(s, FIONBIO, &iMode);
|
|
#else
|
|
assert(0);
|
|
#endif
|
|
}
|