#include "netsock.h"
-// Windows
-#if defined(_WIN32)
-// Variables
-struct WSAData net_wd;
-// Funcs
-#define net_errno() (WSAGetLastError())
-const char *net_strerror(int e) {
+#ifdef _WIN32
+void net_init(void)
+{
+ WSADATA wsaData;
+ int err = WSAStartup(MAKEWORD(2, 0), &wsaData);
+ if (err) {
+ fprintf(stderr, "Winsock API startup failed: %s\n", net_strerror(err));
+ exit(EXIT_FAILURE);
+ }
+ fprintf(stderr, "[NetSock]: WinSock initialized V%d.%d!\n",LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
+}
+void net_cleanup(void)
+{
+ WSACleanup();
+}
+const char *net_strerror(int e)
+{
static char msg[256];
- if (!FormatMessageA(\
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, e, 0, msg, 256, NULL))
+ if (!FormatMessageA(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, e, 0, msg, 256, NULL))
sprintf(msg, "WSA Error %d", e);
return msg;
}
-int net_nonblock(SOCKET fd) {
- u_long v = 1;
- return ioctlsocket(fd, FIONBIO, &v);
-}
+#endif
-// POSIX
-#else
-// Funcs
-int net_nonblock(SOCKET fd) {
-#if defined(O_NONBLOCK)
+int net_nonblock(SOCKET fd)
+{
+#if !defined(_WIN32) && defined(O_NONBLOCK)
int f = fcntl(fd, F_GETFL);
if (f == -1)
return -1;
return ioctlsocket(fd, FIONBIO, &v);
#endif
}
-#endif
-// Funcs
void net_perror(const char *p)
{
- if (p && *p) {
+ if (p && *p)
fprintf(stderr, "%s: %s\n", p, net_strerror(net_errno()));
- } else {
- fprintf(stderr, "%s\n", net_strerror(net_errno()));
- }
-}
-
-// Init and shutdown
-void net_init(void) {
- fprintf(stderr, "[NetSock]: NetSock initializing...\n");
- // Initialize WSA
-#if defined(_WIN32)
- int WStartCode = WSAStartup(MAKEWORD(2, 0), &net_wd);
- if (WStartCode) {
- fprintf(stderr, "Winsock API startup failed: %s\n", net_strerror(WStartCode));
- exit(EXIT_FAILURE);
- }
- fprintf(stderr, "[NetSock]: WinSock initialized V%d.%d!\n",LOBYTE(net_wd.wVersion), HIBYTE(net_wd.wVersion));
-#endif
-}
-void net_cleanup(void) {
- fprintf(stderr, "[NetSock]: NetSock cleaning up...\n");
- // Initialize WSA
-#if defined(_WIN32)
- WSACleanup();
- fprintf(stderr, "[NetSock]: WinSock cleaned up! (probably)\n");
-#endif
-}
-
-// Misc
-ssize_t send_log(SOCKET socket, const char *buffer, size_t length, int flags) {
- fprintf(stderr, "SERVER %"PRISocket": %.*s", socket, (int)length, (char*)buffer);
- if (socket != INVALID_SOCKET)
- return send(socket, buffer, length, flags);
else
- return -1;
-}
-ssize_t recv_log(SOCKET socket, char *buffer, size_t length, int flags) {
- ssize_t bytesRead = recv(socket,buffer,length,flags);
- if(bytesRead > 0) {
- fprintf(stderr, "CLIENT %"PRISocket": %.*s", socket, (int)length, (char*)buffer);
- }
- return bytesRead;
-}
-void net_sleep(unsigned int sec) {
- struct timeval sleeptime;
- sleeptime.tv_sec = sec;
- select(0, NULL, NULL, NULL, &sleeptime);
-}
-void net_usleep(unsigned int usec) {
- struct timeval sleeptime;
- sleeptime.tv_usec = usec;
- select(0, NULL, NULL, NULL, &sleeptime);
+ fprintf(stderr, "%s\n", net_strerror(net_errno()));
}
-#ifndef _netsock_h
-#define _netsock_h
+#ifndef NETSOCK_H_
+#define NETSOCK_H_
+
+/* API comparision table
+ * | POSIX | Win32 | NetSock |
+ * |--------------------|-------------------|------------------|
+ * | int | SOCKET | SOCKET |
+ * | "%d" | (complicated) | "%"PRISocket |
+ * | -1 | INVALID_SOCKET | INVALID_SOCKET |
+ * | errno | WSAGetLastError() | net_errno() |
+ * | strerror | (complicated) | net_strerror() |
+ * | perror | (complicated) | net_perror() |
+ * | EAGAIN | WSAEWOULDBLOCK | net_wouldblock() |
+ * | (none) | WSAStartup() | net_init() |
+ * | (none) | WSACleanup() | net_cleanup() |
+ * | close() | closesocket() | closesocket() |
+ * | ioctl() | ioctlsocket() | ioctlsocket() |
+ * | SHUT_RD | SD_RECEIVE | SHUT_RD |
+ * | SHUT_WR | SD_SEND | SHUT_WR |
+ * | SHUT_RDWR | SD_BOTH | SHUT_RDWR |
+ * | O_NONBLOCK/FIONBIO | FIONBIO | net_nonblock() |
+ * | read/recv | recv | recv |
+ * | write/send | send | send |
+ */
+
+/* All implementations besides glibc and 4.4BSD allow redefining this constant.
+ * Win32 has 64 as default, Linux has 1024. Increase the limit on Win32. */
#define FD_SETSIZE 1024
-#if _WIN32
+
+/* Set target Win32 version to Vista.
+ * In particular, inet_ntop and AI_NUMERICSERV require this. */
+#ifdef _WIN32
#define WINVER 0x0600
#define _WIN32_WINNT 0x0600
#endif
-// Standard headers
+/* Standard headers */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
-// Windows
-#if defined(_WIN32)
+#ifdef _WIN32
+/* Win32 */
+/* Include winsock2.h first, because windows.h defauts to Winsock 1 */
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#ifdef _WIN64
-#define PRISocket "llu" // The format string for SOCKET
+#define PRISocket "llu"
#else
-#define PRISocket "u" // The format string for SOCKET
+#define PRISocket "u"
#endif
#define net_errno() (WSAGetLastError())
-#define net_wouldblock() (WSAGetLastError() == WSAEWOULDBLOCK)
-// Funcs
const char *net_strerror(int e);
-// Variables
-extern struct WSAData net_wd;
+#define net_wouldblock() (WSAGetLastError() == WSAEWOULDBLOCK)
+void net_init(void);
+void net_cleanup(void);
#define SHUT_RD SD_RECEIVE
#define SHUT_WR SD_SEND
#define SHUT_RDWR SD_BOTH
-
-// POSIX
#else
+/* POSIX */
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
-//typedef unsigned long long SOCKET;
+#include <poll.h>
typedef int SOCKET;
-#define PRISocket "d" // The format string for SOCKET
+#define PRISocket "d"
+#define INVALID_SOCKET (-1)
#define net_errno() ((int)errno)
#define net_strerror(e) strerror((e))
#define net_wouldblock() (errno == EAGAIN || errno == EWOULDBLOCK)
+#define net_init()
+#define net_cleanup()
#define closesocket close
#define ioctlsocket ioctl
-#define INVALID_SOCKET -1
-#define SD_RECEIVE SHUT_RD
-#define SD_SEND SHUT_WR
-#define SD_BOTH SHUT_RDWR
#endif
-// Funcs
-int net_nonblock(SOCKET fd);
void net_perror(const char *p);
-void net_init(void);
-void net_cleanup(void);
-ssize_t send_log(SOCKET socket, const char *buffer, size_t length, int flags);
-ssize_t recv_log(SOCKET socket, char *buffer, size_t length, int flags);
-void net_sleep(unsigned int sec);
-void net_usleep(unsigned int usec);
+int net_nonblock(SOCKET fd);
#endif