initial server for Windows
authorLaurent Mazet <laurent.mazet@thalesgroup.com>
Fri, 5 May 2023 08:49:44 +0000 (10:49 +0200)
committerLaurent Mazet <laurent.mazet@thalesgroup.com>
Fri, 5 May 2023 08:49:44 +0000 (10:49 +0200)
debug.c
makefile
webserver.c

diff --git a/debug.c b/debug.c
index 151e615c45f6731cee7f2371f7877a59a03c6c8b..fbf493886bb727b86931c54b4568fece862cf477 100644 (file)
--- 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: */
index b8a856e852aa552bd9a14e7e0735d2ada64269f5..00c9836cb428667d29f6674d1d53af9ab3fe64bd 100644 (file)
--- 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
index 5c95457743b17c10f3a6ce47a5e98d2ddb1554b4..5b438488b42d9e75e9823366d3b182bb13b65960 100644 (file)
@@ -2,11 +2,29 @@
 /* cflags: */
 /* linker: color.o debug.o */
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
+#ifdef _WIN32 /* Windows */
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else /* Posix */
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#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: */