From 82aeff9922ccdd229d95292663f24b6f95b831e1 Mon Sep 17 00:00:00 2001
From: Bruce Cowan <bruce.cowan@strath.ac.uk>
Date: Tue, 13 Aug 2019 11:52:24 +0100
Subject: [PATCH] Add Windows version of previous

---
 meson.build                     | 10 ++++-
 posix/meson.build               |  1 -
 pthread/meson.build             |  2 +-
 sockets/meson.build             |  7 ++++
 sockets/udp-server-win.c        | 69 +++++++++++++++++++++++++++++++++
 {posix => sockets}/udp-server.c |  0
 6 files changed, 85 insertions(+), 4 deletions(-)
 delete mode 100644 posix/meson.build
 create mode 100644 sockets/meson.build
 create mode 100644 sockets/udp-server-win.c
 rename {posix => sockets}/udp-server.c (100%)

diff --git a/meson.build b/meson.build
index 24a7d61..c546225 100644
--- a/meson.build
+++ b/meson.build
@@ -7,12 +7,17 @@ glib_dep = dependency('glib-2.0', version: '>= 2.16', required: false)
 openmp_dep = dependency('openmp', required: false)
 thread_dep = dependency('threads', required: false)
 
-incdir = include_directories('lib')
+if host_machine.system() == 'windows'
+    cc = meson.get_compiler('c')
+	socket_deps = [cc.find_library('ws2_32')]
+else
+    socket_deps = []
+endif
 
 subdir('lib')
 
 executable('add', 'add.c')
-executable('add2', 'add2.c', link_with: lib_utils, include_directories: incdir)
+executable('add2', 'add2.c', link_with: lib_utils, include_directories: 'lib')
 executable('angle', 'angle.c', dependencies: libm)
 executable('binary', 'binary.c')
 executable('complex', 'complex.c', dependencies: libm)
@@ -34,6 +39,7 @@ executable('world', 'world.c')
 subdir('array')
 subdir('hashtable')
 subdir('list')
+subdir('sockets')
 subdir('winter')
 
 if openmp_dep.found()
diff --git a/posix/meson.build b/posix/meson.build
deleted file mode 100644
index 39108b1..0000000
--- a/posix/meson.build
+++ /dev/null
@@ -1 +0,0 @@
-executable('udp-server', 'udp-server.c')
diff --git a/pthread/meson.build b/pthread/meson.build
index 4c3d431..78af5f2 100644
--- a/pthread/meson.build
+++ b/pthread/meson.build
@@ -1,4 +1,4 @@
 executable('thread-incr', 'thread-incr.c',
            dependencies: thread_dep,
            link_with: lib_utils,
-           include_directories: incdir)
+           include_directories: '../lib')
diff --git a/sockets/meson.build b/sockets/meson.build
new file mode 100644
index 0000000..70e4304
--- /dev/null
+++ b/sockets/meson.build
@@ -0,0 +1,7 @@
+if host_machine.system() == 'windows'
+    udp_server_src = ['udp-server-win.c']
+else
+    udp_server_src = ['udp-server.c']
+endif
+
+executable('udp-server', udp_server_src, dependencies: socket_deps)
diff --git a/sockets/udp-server-win.c b/sockets/udp-server-win.c
new file mode 100644
index 0000000..a270016
--- /dev/null
+++ b/sockets/udp-server-win.c
@@ -0,0 +1,69 @@
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <winsock2.h>
+#include <Ws2tcpip.h>
+
+#define PORT 46123
+#define BUF_LENGTH 1024
+
+static SOCKET sock;
+
+static void
+handle_error (const char *funcname)
+{
+    fprintf (stderr, "%s failed: %d\n", funcname, WSAGetLastError ());
+    closesocket (sock);
+    exit (EXIT_FAILURE);
+}
+
+int
+main (void)
+{
+    WSADATA wsa;
+
+    int result = WSAStartup (MAKEWORD (2, 2), &wsa);
+    if (result != 0)
+    {
+        fprintf (stderr, "WSAStartup: %d\n", result);
+        exit (EXIT_FAILURE);
+    }
+
+    if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
+        handle_error ("socket");
+
+    SOCKADDR_IN addr;
+    memset (&addr, 0, sizeof (SOCKADDR_IN));
+    addr.sin_family = AF_INET;
+    addr.sin_port = htons (PORT);
+    addr.sin_addr.s_addr = htonl (INADDR_ANY);
+
+    if (bind (sock, (SOCKADDR *) &addr, sizeof (addr)) == SOCKET_ERROR)
+        handle_error ("bind");
+
+    while (true)
+    {
+        char buf[BUF_LENGTH];
+        struct sockaddr_in src_addr;
+        int addrlen = sizeof (SOCKADDR_IN);
+        char str[INET_ADDRSTRLEN];
+
+        int bytes = recvfrom (sock, buf, BUF_LENGTH, 0,
+                              (SOCKADDR *) &src_addr, &addrlen);
+        if (bytes == SOCKET_ERROR)
+            handle_error ("recvfrom");
+
+        if (InetNtop (AF_INET, &src_addr.sin_addr, str, INET_ADDRSTRLEN) == NULL)
+        {
+            fprintf (stderr, "Could not convert address to string\n");
+            exit (EXIT_FAILURE);
+        }
+
+        printf ("Received %d bytes from %s\n", bytes, str);
+    }
+
+    return 0;
+}
diff --git a/posix/udp-server.c b/sockets/udp-server.c
similarity index 100%
rename from posix/udp-server.c
rename to sockets/udp-server.c
-- 
GitLab