From 184be7817a7af8ecd11799f2ef1365fcaca3b4e2 Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Fri, 5 May 2023 10:49:44 +0200 Subject: [PATCH] initial server for Windows --- debug.c | 2 +- makefile | 5 ++- webserver.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 2 deletions(-) diff --git a/debug.c b/debug.c index 151e615..fbf4938 100644 --- a/debug.c +++ b/debug.c @@ -1,5 +1,5 @@ #include "debug.h" -int verbose = 1; +int verbose = INFO; /* vim: set ts=4 sw=4 et: */ diff --git a/makefile b/makefile index b8a856e..00c9836 100644 --- a/makefile +++ b/makefile @@ -13,6 +13,9 @@ CFLAGS += -W -Wall -Wextra -g CFLAGS += -std=c99 -D_XOPEN_SOURCE=500 CFLAGS += $(OFLAGS) $(INCLUDES) $(GCOV) LDFLAGS += -g $(GCOV) +ifeq ($(OS),Windows_NT) +LDLIBS += -lws2_32 +endif # Targets @@ -132,7 +135,7 @@ valgrind_%: %.exe %.exe: %.o %.d $(call TITLE, "Building $@") - $(CC) $(LDFLAGS) $< $(shell perl -- getcomments.pl -p='linker:\s' -f='%' ${<:.o=.c}) -o $@ + $(CC) $(LDFLAGS) $< $(shell perl -- getcomments.pl -p='linker:\s' -f='%' ${<:.o=.c}) $(LDLIBS) -o $@ $(call PASS, SUCCESS) ## Phony diff --git a/webserver.c b/webserver.c index 5c95457..5b43848 100644 --- a/webserver.c +++ b/webserver.c @@ -2,11 +2,29 @@ /* cflags: */ /* linker: color.o debug.o */ +#include #include #include +#ifdef _WIN32 /* Windows */ +#include +#include +#else /* Posix */ +#include +#include +#include +#include +#endif #include "debug.h" +/* types */ + +#ifdef _WIN32 /* Windows */ +typedef SOCKET socket_t; +#else /* Posix */ +typedef int socket_t; +#endif + /* constants */ #define BUFFER_SIZE 4096 @@ -31,6 +49,83 @@ int usage (int ret) return ret; } +/* open listening socket */ + +socket_t open_listening_socket (int port) +{ +#ifdef _WIN32 /* Windows */ + WSADATA WSAData; + WSAStartup (MAKEWORD(2,0), &WSAData); + assert (INVALID_SOCKET == (socket_t)-1); +#endif + + VERBOSE (DEBUG, fprintf (stdout, "Opening socket\n")); +#ifdef _WIN32 /* Windows */ + socket_t sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock == INVALID_SOCKET) + return -1; +#else /* Posix */ + socket_t sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (socket < 0) + return -1; +#endif + + struct sockaddr_in addr = {0}; +#ifdef _WIN32 /* Windows */ + addr.sin_family = AF_INET; +#else /* Posix */ + addr.sin_family = PF_INET; +#endif + addr.sin_port = htons (port); + addr.sin_addr.s_addr = htonl (INADDR_ANY); + + VERBOSE (DEBUG, fprintf (stdout, "Binding socket\n")); + int rc = bind (sock, (struct sockaddr *)&addr, sizeof (addr)); +#ifdef _WIN32 /* Windows */ + if (rc == SOCKET_ERROR) { + VERBOSE (ERROR, fprintf (stderr, "error: %d\n", WSAGetLastError ())); + if (closesocket (sock) == SOCKET_ERROR) { + VERBOSE (ERROR, fprintf (stderr, "error: %d\n", WSAGetLastError ())); + } +#else /* Posix */ + if (socket < 0) { + VERBOSE (ERROR, fprintf (stderr, "error: %d\n", errno)); + close (sock); +#endif + return -1; + } + + VERBOSE (DEBUG, fprintf (stdout, "Configuring socket\n")); +#ifdef _WIN32 /* Windows */ +#else /* Posix */ + fcntl (sock, F_SETFL, O_NONBLOCK); +#endif + int val = 1; + rc = setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof (val)); + if (rc < 0) { + VERBOSE (ERROR, fprintf (stderr, "%s\n", "setsockopt/TCP_NODELAY")); +#ifdef _WIN32 /* Windows */ + closesocket (sock); +#else /* Posix */ + close (sock); +#endif + return -1; + } + + return sock; +} + +/* close listening socket */ +void close_listening_socket (socket_t sock) +{ +#ifdef _WIN32 /* Windows */ + closesocket (sock); + WSACleanup (); +#else /* Posix */ + close (sock); +#endif +} + /* main function */ int main (int argc, char *argv[]) @@ -86,6 +181,19 @@ int main (int argc, char *argv[]) } } + VERBOSE (DEBUG, fprintf (stdout, "Initializing socket\n")); + socket_t sock = open_listening_socket (port); + if (sock == (socket_t)-1) { + VERBOSE (ERROR, fprintf (stderr, "Can't open listening socket\n")); + return 1; + } + + VERBOSE (INFO, fprintf (stdout, "Listening socket on port %d\n", port)); + sleep (2); + + VERBOSE (DEBUG, fprintf (stdout, "Closing socket\n")); + close_listening_socket (sock); + return ret; } @@ -97,5 +205,7 @@ int main (int argc, char *argv[]) // test: webserver.exe -v 2>&1 | grep -q 'missing verbose level' // test: webserver.exe -p 2>&1 | grep -q 'missing port number' // test: webserver.exe -p -1 2>&1 | grep -q 'incorrect port number' +// test: webserver.exe | grep -q 'Listening socket on port 8080' +// test: webserver.exe -p 8000 | grep -q 'Listening socket on port 8000' /* vim: set ts=4 sw=4 et: */ -- 2.30.2