gnugo-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnugo-devel] socket support for Windows: second generation patch


From: Paul Pogonyshev
Subject: [gnugo-devel] socket support for Windows: second generation patch
Date: Sun, 26 Dec 2004 00:48:07 +0200
User-agent: KMail/1.4.3

This patch works in a different way: it #define's different
stdio functions to internal implementations of them, which
in turn either call the normal stdio functions, or send()/
recv().

For sane systems there are no changes.  For them all added
functionality is effectively #if 0'd out.

This patch is also almost finished.  The only missing thing
is update for Windows project.  Help is welcome.

Paul


Index: engine/board.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/board.h,v
retrieving revision 1.19
diff -u -p -r1.19 board.h
--- engine/board.h      7 Dec 2004 04:31:05 -0000       1.19
+++ engine/board.h      25 Dec 2004 22:36:04 -0000
@@ -24,6 +24,7 @@
 #define _BOARD_H_
 
 #include "sgftree.h"
+#include "winsocket.h"
 #include "config.h"
 #include <stdarg.h>
 
Index: engine/gnugo.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/gnugo.h,v
retrieving revision 1.116
diff -u -p -r1.116 gnugo.h
--- engine/gnugo.h      13 Nov 2004 04:46:43 -0000      1.116
+++ engine/gnugo.h      25 Dec 2004 22:36:05 -0000
@@ -43,6 +43,7 @@
 
 #include "sgftree.h"
 #include "clock.h"
+#include "winsocket.h"
 
 /* interface.c */
 /* Initialize the whole thing. Should be called once. */
Index: engine/influence.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/influence.h,v
retrieving revision 1.22
diff -u -p -r1.22 influence.h
--- engine/influence.h  24 Jan 2004 04:04:56 -0000      1.22
+++ engine/influence.h  25 Dec 2004 22:36:15 -0000
@@ -26,7 +26,7 @@
 #include <string.h>
 
 #include "liberty.h"
-
+#include "winsocket.h"
 
 
 /* The cosmic style uses more influence than the defaults attenuation 
Index: engine/liberty.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v
retrieving revision 1.233
diff -u -p -r1.233 liberty.h
--- engine/liberty.h    18 Dec 2004 19:32:43 -0000      1.233
+++ engine/liberty.h    25 Dec 2004 22:36:15 -0000
@@ -26,6 +26,7 @@
 #include "board.h"
 #include "hash.h"
 #include "gnugo.h"
+#include "winsocket.h"
 
 /* ================================================================ */
 /*                           public variables                       */
Index: interface/gtp.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/gtp.h,v
retrieving revision 1.16
diff -u -p -r1.16 gtp.h
--- interface/gtp.h     11 Oct 2004 21:03:28 -0000      1.16
+++ interface/gtp.h     25 Dec 2004 22:36:15 -0000
@@ -38,6 +38,9 @@
  * without prior written authorization of the copyright holder.  *
 \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
+/* NOTE: GNU Go specific, workarounds dumb Windows sockets. */
+#include "winsocket.h"
+
 #include <stdarg.h>
 #include <stdio.h>
 
Index: interface/main.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/main.c,v
retrieving revision 1.109
diff -u -p -r1.109 main.c
--- interface/main.c    7 Dec 2004 04:50:02 -0000       1.109
+++ interface/main.c    25 Dec 2004 22:36:15 -0000
@@ -49,6 +49,7 @@
 
 #include "gg-getopt.h"
 #include "gg_utils.h"
+#include "winsocket.h"
 
 #include "interface.h"
 #include "sgftree.h"
@@ -1687,11 +1688,37 @@ show_copyright(void)
 #if ENABLE_SOCKET_SUPPORT
 
 
+#if !defined(_WIN32) && !defined(_WIN32_WCE)
+
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 
+#define closesocket    close
+#define init_sockets()
+
+#else  /* on Windows */
+
+
+#include <winsocket.h>
+
+
+static void
+init_sockets(void)
+{
+  WSADATA data;
+  WORD version = MAKEWORD(1, 1);
+
+  if (WSAStartup(version, &data) != NO_ERROR) {
+    fprintf(stderr, "WSAStartup() failed with error %d\n", WSAGetLastError());
+    exit(EXIT_FAILURE);
+  }
+}
+
+
+#endif /* on Windows */
+
 
 static void
 socket_connect_to(const char *host_name, unsigned int port,
@@ -1702,6 +1729,8 @@ socket_connect_to(const char *host_name,
   struct hostent *host_data;
   char **address_pointer;
 
+  init_sockets();
+
   if (!host_name)
     host_name = "127.0.0.1";
 
@@ -1732,12 +1761,23 @@ socket_connect_to(const char *host_name,
 
   if (! *address_pointer) {
     fprintf(stderr, "Failed to connect to %s:%d\n", host_data->h_name, port);
-    close(connection_socket);
+    closesocket(connection_socket);
     exit(EXIT_FAILURE);
   }
 
+#if !USE_WINDOWS_SOCKET_CLUDGE
+
   *input_file  = fdopen(connection_socket, "r");
   *output_file = fdopen(dup(connection_socket), "w");
+
+#else  /* USE_WINDOWS_SOCKET_CLUDGE */
+
+  winsocket_activate(connection_socket);
+
+  *input_file  = NULL;
+  *output_file = NULL;
+
+#endif /* USE_WINDOWS_SOCKET_CLUDGE */
 }
 
 
@@ -1749,6 +1789,8 @@ socket_listen_at(const char *host_name, 
   int listening_socket;
   int connection_socket;
 
+  init_sockets();
+
   if (host_name) {
     struct hostent *host_data;
 
@@ -1794,14 +1836,25 @@ socket_listen_at(const char *host_name, 
     else
       fprintf(stderr, "Failed to listen on port %d\n", port);
 
-    close(listening_socket);
+    closesocket(listening_socket);
     exit(EXIT_FAILURE);
   }
 
-  close(listening_socket);
+  closesocket(listening_socket);
+
+#if !USE_WINDOWS_SOCKET_CLUDGE
 
   *input_file  = fdopen(connection_socket, "r");
   *output_file = fdopen(dup(connection_socket), "w");
+
+#else  /* USE_WINDOWS_SOCKET_CLUDGE */
+
+  winsocket_activate(connection_socket);
+
+  *input_file  = NULL;
+  *output_file = NULL;
+
+#endif /* USE_WINDOWS_SOCKET_CLUDGE */
 }
 
 
Index: patterns/Makefile.am
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/Makefile.am,v
retrieving revision 1.28
diff -u -p -r1.28 Makefile.am
--- patterns/Makefile.am        11 Jun 2004 14:20:07 -0000      1.28
+++ patterns/Makefile.am        25 Dec 2004 22:36:15 -0000
@@ -53,6 +53,7 @@ joseki_SOURCES = joseki.c 
 joseki_LDADD = ../engine/libboard.a ../sgf/libsgf.a ../utils/libutils.a 
 joseki_INCLUDES = -I$(top_srcdir)/sgf
 mkeyes_SOURCES = mkeyes.c
+mkeyes_LDADD = ../utils/libutils.a
 extract_fuseki_SOURCES  = extract_fuseki.c
 # Yes, we currently need duplicate libengine.a and libpatterns.a.
 extract_fuseki_LDADD = ../engine/libengine.a libpatterns.a\
Index: patterns/Makefile.in
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/Makefile.in,v
retrieving revision 1.47
diff -u -p -r1.47 Makefile.in
--- patterns/Makefile.in        11 Jun 2004 14:20:07 -0000      1.47
+++ patterns/Makefile.in        25 Dec 2004 22:36:22 -0000
@@ -130,6 +130,7 @@ joseki_SOURCES = joseki.c 
 joseki_LDADD = ../engine/libboard.a ../sgf/libsgf.a ../utils/libutils.a 
 joseki_INCLUDES = -I$(top_srcdir)/sgf
 mkeyes_SOURCES = mkeyes.c
+mkeyes_LDADD = ../utils/libutils.a
 extract_fuseki_SOURCES = extract_fuseki.c
 # Yes, we currently need duplicate libengine.a and libpatterns.a.
 extract_fuseki_LDADD = ../engine/libengine.a libpatterns.a\
@@ -212,8 +213,7 @@ joseki_DEPENDENCIES = ../engine/libboard
 joseki_LDFLAGS =
 am_mkeyes_OBJECTS = mkeyes.$(OBJEXT)
 mkeyes_OBJECTS = $(am_mkeyes_OBJECTS)
-mkeyes_LDADD = $(LDADD)
-mkeyes_DEPENDENCIES =
+mkeyes_DEPENDENCIES = ../utils/libutils.a
 mkeyes_LDFLAGS =
 am_mkpat_OBJECTS = mkpat.$(OBJEXT) transform.$(OBJEXT) dfa.$(OBJEXT)
 mkpat_OBJECTS = $(am_mkpat_OBJECTS)
Index: utils/Makefile.am
===================================================================
RCS file: /cvsroot/gnugo/gnugo/utils/Makefile.am,v
retrieving revision 1.3
diff -u -p -r1.3 Makefile.am
--- utils/Makefile.am   6 Sep 2001 21:34:21 -0000       1.3
+++ utils/Makefile.am   25 Dec 2004 22:36:22 -0000
@@ -2,9 +2,9 @@ noinst_LIBRARIES = libutils.a
 
 EXTRA_DIST = utils.dsp
 
-libutils_a_SOURCES = getopt.c getopt1.c random.c gg_utils.c
+libutils_a_SOURCES = getopt.c getopt1.c random.c gg_utils.c winsocket.c
 
-noinst_HEADERS = gg-getopt.h random.h gg_utils.h
+noinst_HEADERS = gg-getopt.h random.h gg_utils.h winsocket.h
 
 # Remove these files here... they are created locally
 DISTCLEANFILES = *~
Index: utils/Makefile.in
===================================================================
RCS file: /cvsroot/gnugo/gnugo/utils/Makefile.in,v
retrieving revision 1.25
diff -u -p -r1.25 Makefile.in
--- utils/Makefile.in   2 Aug 2003 14:17:52 -0000       1.25
+++ utils/Makefile.in   25 Dec 2004 22:36:22 -0000
@@ -80,9 +80,9 @@ noinst_LIBRARIES = libutils.a
 
 EXTRA_DIST = utils.dsp
 
-libutils_a_SOURCES = getopt.c getopt1.c random.c gg_utils.c
+libutils_a_SOURCES = getopt.c getopt1.c random.c gg_utils.c winsocket.c
 
-noinst_HEADERS = gg-getopt.h random.h gg_utils.h
+noinst_HEADERS = gg-getopt.h random.h gg_utils.h winsocket.h
 
 # Remove these files here... they are created locally
 DISTCLEANFILES = *~
@@ -95,7 +95,7 @@ LIBRARIES = $(noinst_LIBRARIES)
 libutils_a_AR = $(AR) cru
 libutils_a_LIBADD =
 am_libutils_a_OBJECTS = getopt.$(OBJEXT) getopt1.$(OBJEXT) \
-       random.$(OBJEXT) gg_utils.$(OBJEXT)
+       random.$(OBJEXT) gg_utils.$(OBJEXT) winsocket.$(OBJEXT)
 libutils_a_OBJECTS = $(am_libutils_a_OBJECTS)
 
 DEFS = @DEFS@
@@ -105,7 +105,8 @@ LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 @address@hidden = $(DEPDIR)/getopt.Po $(DEPDIR)/getopt1.Po \
address@hidden@ $(DEPDIR)/gg_utils.Po $(DEPDIR)/random.Po
address@hidden@ $(DEPDIR)/gg_utils.Po $(DEPDIR)/random.Po \
address@hidden@ $(DEPDIR)/winsocket.Po
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
@@ -148,6 +149,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @address@hidden(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden(DEPDIR)/address@hidden@
 
 distclean-depend:
        -rm -rf $(DEPDIR)
Index: utils/winsocket.c
===================================================================
RCS file: utils/winsocket.c
diff -N utils/winsocket.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ utils/winsocket.c   25 Dec 2004 22:36:22 -0000
@@ -0,0 +1,235 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * This is GNU Go, a Go program. Contact address@hidden, or see       *
+ * http://www.gnu.org/software/gnugo/ for more information.          *
+ *                                                                   *
+ * Copyright 2004 by the Free Software Foundation.                   *
+ *                                                                   *
+ * This program is free software; you can redistribute it and/or     *
+ * modify it under the terms of the GNU General Public License as    *
+ * published by the Free Software Foundation - version 2             *
+ *                                                                   *
+ * This program is distributed in the hope that it will be useful,   *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     *
+ * GNU General Public License in file COPYING for more details.      *
+ *                                                                   *
+ * You should have received a copy of the GNU General Public         *
+ * License along with this program; if not, write to the Free        *
+ * Software Foundation, Inc., 59 Temple Place - Suite 330,           *
+ * Boston, MA 02111, USA.                                            *
+\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* Workaround M$ Windows C library deficiency: it cannot handle
+ * sockets as stdio streams.  So we do this ourselves, more or less.
+ *
+ * Call winsocket_activate(...) with socket handle to use.  After this
+ * fake stream NULL will work over the socket, while other streams
+ * will (hopefully) keep working as usual.
+ */
+
+#define WINSOCKET_H_INTERNAL_INCLUSION
+
+#include "winsocket.h"
+
+
+#if USE_WINDOWS_SOCKET_CLUDGE
+
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <winsock.h>
+
+
+static int socket_handle      = 0;
+static int socket_end_of_file = 0;
+
+
+void
+winsocket_activate(int _socket_handle)
+{
+  assert(socket_handle == 0);
+  socket_handle = _socket_handle;
+}
+
+
+/* Miscellaneous functions. */
+
+void
+winsocket_setbuf(FILE *file, char *buffer)
+{
+  if (file != NULL)
+    setbuf(file, buffer);
+  else
+    assert(socket_handle != 0);
+}
+
+
+int
+winsocket_fflush(FILE *file)
+{
+  if (file != NULL)
+    return fflush(file);
+  else {
+    assert(socket_handle != 0);
+    return 0;
+  }
+}
+
+
+int
+winsocket_feof(FILE *file)
+{
+  if (file != NULL)
+    return feof(file);
+  else {
+    assert(socket_handle != 0);
+    return socket_end_of_file;
+  }
+}
+
+
+int
+winsocket_fclose(FILE *file)
+{
+  if (file != NULL)
+    return fclose(file);
+  else {
+    assert(socket_handle != 0);
+    return 0;
+  }
+}
+
+
+/* Input functions. */
+
+size_t
+winsocket_fread(void *buffer, size_t size, size_t num_items, FILE *file)
+{
+  if (file != NULL)
+    return fread(buffer, size, num_items, file);
+  else {
+    assert(socket_handle != 0);
+    if (recv(socket_handle, (char *) buffer, size * num_items, 0)
+       == size * num_items)
+      return num_items;
+    else {
+      socket_end_of_file = 1;
+      return EOF;
+    }
+  }
+}
+
+
+char *
+winsocket_fgets(char *buffer, int size, FILE *file)
+{
+  if (file != NULL)
+    return fgets(buffer, size, file);
+  else {
+    /* FIXME: Optimize if reading char-by-char is too slow. */
+    int stored_length;
+
+    for (stored_length = 0; stored_length < size - 1; stored_length) {
+      if (recv(socket_handle, buffer + stored_length, 1, 0) != 1) {
+       socket_end_of_file = 1;
+       break;
+      }
+
+      if (buffer[stored_length++] == '\n')
+       break;
+    }
+
+    if (stored_length == 0)
+      return NULL;
+
+    buffer[stored_length + 1] = 0;
+    return buffer;
+  }
+}
+
+
+/* Output functions. */
+
+size_t
+winsocket_fwrite(const void *buffer, size_t size, size_t num_items,
+                FILE *file)
+{
+  if (file != NULL)
+    return fwrite(buffer, size, num_items, file);
+  else {
+    assert(socket_handle != 0);
+    return ((send(socket_handle, (const char *) buffer, size * num_items, 0)
+            == size * num_items)
+           ? num_items : EOF);
+  }
+}
+
+
+int
+winsocket_fputc(int character, FILE *file)
+{
+  if (file != NULL)
+    return fputc(character, file);
+  else {
+    assert(socket_handle != 0);
+    return (send(socket_handle, (const char *) &character, 1, 0) == 1
+           ? character : EOF);
+  }
+}
+
+
+int
+winsocket_fputs(const char *string, FILE *file)
+{
+  if (file != NULL)
+    return fputs(string, file);
+  else {
+    int length = strlen(string);
+
+    assert(socket_handle != 0);
+    return send(socket_handle, string, length, 0) == length ? length : EOF;
+  }
+}
+
+
+int
+winsocket_fprintf(FILE *file, const char *format_string, ...)
+{
+  va_list arguments;
+  int result;
+
+  va_start(arguments, format_string);
+  result = winsocket_vfprintf(file, format_string, arguments);
+  va_end(arguments);
+
+  return result;
+}
+
+
+int
+winsocket_vfprintf(FILE *file, const char *format_string, va_list arguments)
+{
+  if (file != NULL)
+    return vfprintf(file, format_string, arguments);
+  else {
+    char buffer[0x1000];
+    int length = _vsnprintf(buffer, sizeof buffer, format_string, arguments);
+
+    assert(socket_handle != 0);
+    return send(socket_handle, buffer, length, 0) == length ? length : -1;
+  }
+}
+
+
+#endif /* USE_WINDOWS_SOCKET_CLUDGE */
+
+
+/*
+ * Local Variables:
+ * tab-width: 8
+ * c-basic-offset: 2
+ * End:
+ */
Index: utils/winsocket.h
===================================================================
RCS file: utils/winsocket.h
diff -N utils/winsocket.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ utils/winsocket.h   25 Dec 2004 22:36:22 -0000
@@ -0,0 +1,103 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * This is GNU Go, a Go program. Contact address@hidden, or see       *
+ * http://www.gnu.org/software/gnugo/ for more information.          *
+ *                                                                   *
+ * Copyright 2004 by the Free Software Foundation.                   *
+ *                                                                   *
+ * This program is free software; you can redistribute it and/or     *
+ * modify it under the terms of the GNU General Public License as    *
+ * published by the Free Software Foundation - version 2             *
+ *                                                                   *
+ * This program is distributed in the hope that it will be useful,   *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     *
+ * GNU General Public License in file COPYING for more details.      *
+ *                                                                   *
+ * You should have received a copy of the GNU General Public         *
+ * License along with this program; if not, write to the Free        *
+ * Software Foundation, Inc., 59 Temple Place - Suite 330,           *
+ * Boston, MA 02111, USA.                                            *
+\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+#ifndef GNU_GO_WINSOCKET_H
+#define GNU_GO_WINSOCKET_H
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#define USE_WINDOWS_SOCKET_CLUDGE              \
+  ((defined(_WIN32) || defined(_WIN32_WCE))    \
+   && defined(ENABLE_SOCKET_SUPPORT))
+
+
+#if USE_WINDOWS_SOCKET_CLUDGE
+
+
+#include <stdarg.h>
+#include <stdio.h>
+
+
+#ifndef WINSOCKET_H_INTERNAL_INCLUSION
+
+/* (sic.) Teh cludge. */
+
+/* At least in some versions of `stdio.h' on Windows, feof() is a
+ * macro, not a function.
+ */
+#ifdef feof
+#undef feof
+#endif
+
+#define setbuf         winsocket_setbuf
+#define fflush         winsocket_fflush
+#define feof           winsocket_feof
+#define fclose         winsocket_fclose
+
+#define fread          winsocket_fread
+#define fgets          winsocket_fgets
+
+#define fwrite         winsocket_fwrite
+#define fputc          winsocket_fputc
+#define fputs          winsocket_fputs
+#define fprintf                winsocket_fprintf
+#define vfprintf       winsocket_vfprintf
+
+#endif /* WINSOCKET_H_INTERNAL_INCLUSION */
+
+
+void           winsocket_activate(int _socket_handle);
+
+void           winsocket_setbuf(FILE *file, char *buffer);
+int            winsocket_fflush(FILE *file);
+int            winsocket_feof(FILE *file);
+int            winsocket_fclose(FILE *file);
+
+size_t         winsocket_fread(void *buffer,
+                               size_t size, size_t num_items, FILE *file);
+char *         winsocket_fgets(char *buffer, int size, FILE *file);
+
+size_t         winsocket_fwrite(const void *buffer,
+                                size_t size, size_t num_items, FILE *file);
+int            winsocket_fputc(int character, FILE *file);
+int            winsocket_fputs(const char *string, FILE *file);
+int            winsocket_fprintf(FILE *file, const char *format_string, ...);
+int            winsocket_vfprintf(FILE *file, const char *format_string,
+                                  va_list arguments);
+
+
+#endif /* USE_WINDOWS_SOCKET_CLUDGE */
+
+
+#endif /* GNU_GO_WINSOCKET_H */
+
+
+/*
+ * Local Variables:
+ * tab-width: 8
+ * c-basic-offset: 2
+ * End:
+ */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]