[Top][All Lists]
[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:
+ */
- [gnugo-devel] socket support for Windows: second generation patch,
Paul Pogonyshev <=