gnugo-devel
[Top][All Lists]
Advanced

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

Re: [gnugo-devel] TCP/IP connection built into GNU Go?


From: Paul Pogonyshev
Subject: Re: [gnugo-devel] TCP/IP connection built into GNU Go?
Date: Sun, 10 Oct 2004 18:08:34 -0200
User-agent: KMail/1.4.3

I wrote:
> Dan wrote:
> > Paul wrote:
> > > Remaining is a proper `configure' stuff.  Any volunteers?
> >
> > I suppose you mean you want to be able to set
> >
> >       OPT_GTP_CONNECT
> >       OPT_GTP_LISTEN
> >
> > by configure --gtp-connect=... --gtp-listen=...
> >
> > Is that what you want?
>
> No.  Just socket functions are not very portable, so it would
> be wise to make some `configure' tests for headers and functions.
> Also, it seems that on Solaris one needs to compile with certain
> libraries.  On other systems (i.e. GNU/Linux) the functions seem
> to be in C library, and so no additional `-l' flags are needed.
> We can also provide an option to compile without socket support.

I think I found a good solution of configuration problem.  This
version of the patch is probably good enough to commit it to CVS.
If no one objects, I'll do it tomorrow (in the development branch
only, it's probably too late for 3.6.)

Dan, you'll need to run `autoheader' and `autoconf'.  I don't
know what version you use, but here version 2.53 produced many
warnings (2.57 didn't seem to work at all.)

Paul



Index: configure.in
===================================================================
RCS file: /cvsroot/gnugo/gnugo/configure.in,v
retrieving revision 1.112
diff -u -p -r1.112 configure.in
--- configure.in        21 Aug 2004 21:53:29 -0000      1.112
+++ configure.in        10 Oct 2004 14:59:33 -0000
@@ -119,6 +119,10 @@ AC_ARG_ENABLE(alternate-connections,
   --disable-alternate-connections    use primary experimental connection 
                                          analysis (default)])
 
+AC_ARG_ENABLE(socket-support,
+ [  --disable-socket-support           don't compile GTP over TCP/IP support
+  --enable-socket-support            compile TCP/IP support (default)])
+
 AC_ARG_ENABLE(profile,
  [  --enable-profile                   compile gnugo with gprof option ])
 
@@ -552,12 +556,56 @@ else
   GNUGO_SOME_WARNINGS=''
 fi
 
+
 dnl Now lines in Makefile.am can be prefixed @GCC_ONLY@, and
 dnl we can specify either @GNUGO_SOME_WARNINGS@
 
 dnl FIXME: please add warnings for other compilers !
 
 
+AH_TEMPLATE([ENABLE_SOCKET_SUPPORT],
+[Compile support for GTP communication over TCP/IP channel.])
+
+if test "$enable_socket_support" != "no"; then
+  # Check for all required headers, macros, structures and functions
+  # at once.
+  AC_CACHE_CHECK(
+       [whether socket support can be compiled],
+       gnugo_cv_sockets_supported,
+       AC_TRY_LINK([#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>],
+[[  struct sockaddr_in A;
+  struct hostent H;
+  A.sin_family = AF_INET;
+  A.sin_addr.s_addr = htonl(INADDR_ANY);
+  A.sin_port = htons(0);
+  gethostbyname(0);
+  socket(PF_INET, SOCK_STREAM, 0);
+  connect(0, 0, 0);
+  bind(0, 0, 0);
+  listen(0, 0);
+  accept(0, 0, 0);]],
+       gnugo_cv_sockets_supported="yes",
+       gnugo_cv_sockets_supported="no"))
+
+  if test "$gnugo_cv_sockets_supported" = "yes"; then
+    AC_DEFINE(ENABLE_SOCKET_SUPPORT)
+  else
+    if test "$enable_socket_support" = "yes"; then
+      AC_MSG_ERROR(
+[[
+*** Socket support was requested, but cannot be compiled on your system. ***
+*** If you think this is a mistake, please report it to <address@hidden>. 
***]]);
+    else
+      AC_MSG_WARN(
+[[
+*** Unable to compile socket support on your system.  It will be disabled. ***
+***  If you think this is a mistake, please report it to <address@hidden>.  
***]]);
+    fi
+  fi
+fi
 
 #AM_GNU_GETTEXT
 #AC_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl)
Index: engine/liberty.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v
retrieving revision 1.227
diff -u -p -r1.227 liberty.h
--- engine/liberty.h    13 Sep 2004 10:45:11 -0000      1.227
+++ engine/liberty.h    10 Oct 2004 14:59:37 -0000
@@ -412,7 +412,7 @@ void add_shape_value(int pos, float valu
 void add_followup_value(int pos, float value);
 void add_reverse_followup_value(int pos, float value);
 int list_move_reasons(FILE *out, int pos);
-void print_all_move_values(void);
+void print_all_move_values(FILE *output);
 void record_top_move(int move, float val);
 void remove_top_move(int move);
 void scale_randomness(int pos, float scaling);
Index: engine/value_moves.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/value_moves.c,v
retrieving revision 1.131
diff -u -p -r1.131 value_moves.c
--- engine/value_moves.c        13 Sep 2004 10:45:11 -0000      1.131
+++ engine/value_moves.c        10 Oct 2004 14:59:45 -0000
@@ -3203,7 +3203,7 @@ value_moves(int color, float pure_threat
 /* Print the values of all moves with values bigger than zero. */
 
 void
-print_all_move_values()
+print_all_move_values(FILE *output)
 {
   int pos;
   
@@ -3211,7 +3211,7 @@ print_all_move_values()
     if (!ON_BOARD(pos) || move[pos].final_value <= 0.0)
       continue;
       
-    mprintf("%1M %f\n", pos, move[pos].final_value);
+    gfprintf(output, "%1M %f\n", pos, move[pos].final_value);
   }
 }
 
Index: interface/gtp.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/gtp.c,v
retrieving revision 1.19
diff -u -p -r1.19 gtp.c
--- interface/gtp.c     25 May 2004 03:13:47 -0000      1.19
+++ interface/gtp.c     10 Oct 2004 14:59:48 -0000
@@ -69,10 +69,17 @@ static gtp_transform_ptr vertex_transfor
  */
 static int current_id;
 
+/* The file all GTP output goes to.  This is made global for the user
+ * of this file may want to use functions other than gtp_printf() etc.
+ * Set by gtp_main_loop().
+ */
+FILE *gtp_output_file = NULL;
+
+
 /* Read filehandle gtp_input linewise and interpret as GTP commands. */
 void
-gtp_main_loop(struct gtp_command commands[], FILE *gtp_input,
-             FILE *gtp_dump_commands)
+gtp_main_loop(struct gtp_command commands[],
+             FILE *gtp_input, FILE *gtp_output, FILE *gtp_dump_commands)
 {
   char line[GTP_BUFSIZE];
   char command[GTP_BUFSIZE];
@@ -80,7 +87,9 @@ gtp_main_loop(struct gtp_command command
   int i;
   int n;
   int status = GTP_OK;
-  
+
+  gtp_output_file = gtp_output;
+
   while (status == GTP_OK) {
     /* Read a line from gtp_input. */
     if (!fgets(line, GTP_BUFSIZE, gtp_input))
@@ -180,25 +189,25 @@ gtp_mprintf(const char *fmt, ...)
       {
        /* rules of promotion => passed as int, not char */
        int c = va_arg(ap, int);
-       putc(c, stdout);
+       putc(c, gtp_output_file);
        break;
       }
       case 'd':
       {
        int d = va_arg(ap, int);
-       fprintf(stdout, "%d", d);
+       fprintf(gtp_output_file, "%d", d);
        break;
       }
       case 'f':
       {
        double f = va_arg(ap, double); /* passed as double, not float */
-       fprintf(stdout, "%f", f);
+       fprintf(gtp_output_file, "%f", f);
        break;
       }
       case 's':
       {
        char *s = va_arg(ap, char *);
-       fputs(s, stdout);
+       fputs(s, gtp_output_file);
        break;
       }
       case 'm':
@@ -212,20 +221,21 @@ gtp_mprintf(const char *fmt, ...)
       {
        int color = va_arg(ap, int);
        if (color == WHITE)
-         fputs("white", stdout);
+         fputs("white", gtp_output_file);
        else if (color == BLACK)
-         fputs("black", stdout);
+         fputs("black", gtp_output_file);
        else
-         fputs("empty", stdout);
+         fputs("empty", gtp_output_file);
        break;
       }
       default:
-       fprintf(stdout, "\n\nUnknown format character '%c'\n", *fmt);
+       /* FIXME: Should go to `stderr' instead? */
+       fprintf(gtp_output_file, "\n\nUnknown format character '%c'\n", *fmt);
        break;
       }
     }
     else
-      putc(*fmt, stdout);
+      putc(*fmt, gtp_output_file);
   }
   va_end(ap);
 }
@@ -237,7 +247,7 @@ gtp_printf(const char *format, ...)
 {
   va_list ap;
   va_start(ap, format);
-  vfprintf(stdout, format, ap);
+  vfprintf(gtp_output_file, format, ap);
   va_end(ap);
 }
 
@@ -278,7 +288,7 @@ gtp_success(const char *format, ...)
   va_list ap;
   gtp_start_response(GTP_SUCCESS);
   va_start(ap, format);
-  vfprintf(stdout, format, ap);
+  vfprintf(gtp_output_file, format, ap);
   va_end(ap);
   return gtp_finish_response();
 }
@@ -291,7 +301,7 @@ gtp_failure(const char *format, ...)
   va_list ap;
   gtp_start_response(GTP_FAILURE);
   va_start(ap, format);
-  vfprintf(stdout, format, ap);
+  vfprintf(gtp_output_file, format, ap);
   va_end(ap);
   return gtp_finish_response();
 }
Index: interface/gtp.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/gtp.h,v
retrieving revision 1.15
diff -u -p -r1.15 gtp.h
--- interface/gtp.h     24 Jan 2004 04:04:56 -0000      1.15
+++ interface/gtp.h     10 Oct 2004 14:59:48 -0000
@@ -65,8 +65,8 @@ struct gtp_command {
   gtp_fn_ptr function;
 };
 
-void gtp_main_loop(struct gtp_command commands[], FILE *gtp_input,
-                  FILE *gtp_dump_commands);
+void gtp_main_loop(struct gtp_command commands[],
+                  FILE *gtp_input, FILE *gtp_output, FILE *gtp_dump_commands);
 void gtp_internal_set_boardsize(int size);
 void gtp_set_vertex_transform_hooks(gtp_transform_ptr in,
                                    gtp_transform_ptr out);
@@ -83,6 +83,8 @@ int gtp_decode_move(char *s, int *color,
 void gtp_print_vertices(int n, int movei[], int movej[]);
 void gtp_print_vertex(int i, int j);
 
+extern FILE *gtp_output_file;
+
 /*
  * Local Variables:
  * tab-width: 8
Index: interface/interface.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/interface.h,v
retrieving revision 1.15
diff -u -p -r1.15 interface.h
--- interface/interface.h       24 Jan 2004 04:04:56 -0000      1.15
+++ interface/interface.h       10 Oct 2004 14:59:48 -0000
@@ -35,7 +35,7 @@ void play_ascii(SGFTree *tree, Gameinfo 
                char *filename, char *until);
 void play_ascii_emacs(SGFTree *tree, Gameinfo *gameinfo, 
                      char *filename, char *until);
-void play_gtp(FILE *gtp_input, FILE *gtp_dump_commands,
+void play_gtp(FILE *gtp_input, FILE *gtp_output, FILE *gtp_dump_commands,
              int gtp_initial_orientation);
 void play_gmp(Gameinfo *gameinfo, int simplified);
 void play_solo(Gameinfo *gameinfo, int benchmark);
Index: interface/main.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/main.c,v
retrieving revision 1.103
diff -u -p -r1.103 main.c
--- interface/main.c    8 Sep 2004 17:03:42 -0000       1.103
+++ interface/main.c    10 Oct 2004 14:59:51 -0000
@@ -60,6 +60,14 @@ static void show_help(void);
 static void show_debug_help(void);
 static void show_debug_flags(void);
 
+static void socket_connect_to(const char *host_name, unsigned int port,
+                             FILE **input_file, FILE **output_file);
+static void socket_listen_at(const char *host_name, unsigned int port,
+                            FILE **input_file, FILE **output_file);
+static void socket_close_connection(FILE *input_file, FILE *output_file);
+static void socket_stop_listening(FILE *input_file, FILE *output_file);
+
+
 /* long options which have no short form */
 enum {OPT_BOARDSIZE = 127,
       OPT_HANDICAPSTONES,
@@ -74,6 +82,8 @@ enum {OPT_BOARDSIZE = 127,
       OPT_OUTFILE, 
       OPT_QUIET,
       OPT_GTP_INPUT,
+      OPT_GTP_CONNECT,
+      OPT_GTP_LISTEN,
       OPT_GTP_DUMP_COMMANDS,
       OPT_GTP_INITIAL_ORIENTATION,
       OPT_GTP_VERSION,
@@ -189,6 +199,8 @@ static struct gg_option const long_optio
   {"quiet",          no_argument,       0, OPT_QUIET},
   {"silent",         no_argument,       0, OPT_QUIET},
   {"gtp-input",      required_argument, 0, OPT_GTP_INPUT},
+  {"gtp-connect",    required_argument, 0, OPT_GTP_CONNECT},
+  {"gtp-listen",     required_argument, 0, OPT_GTP_LISTEN},
   {"gtp-dump-commands", required_argument, 0, OPT_GTP_DUMP_COMMANDS},
   {"orientation",    required_argument, 0, OPT_GTP_INITIAL_ORIENTATION},
   {"gtp-initial-orientation",
@@ -311,6 +323,8 @@ main(int argc, char *argv[])
   char *outflags = NULL;
   char *gtpfile = NULL;
   char *gtp_dump_commands_file = NULL;
+  int gtp_tcp_ip_mode = 0;
+  char *gtp_tcp_ip_address = NULL;
   
   char *printsgffile = NULL;
   
@@ -319,8 +333,6 @@ main(int argc, char *argv[])
   char debuginfluence_move[4] = "\0";
   
   int benchmark = 0;  /* benchmarking mode (-b) */
-  FILE *gtp_input_FILE;
-  FILE *gtp_dump_commands_FILE = NULL;
   FILE *output_check;
   int orientation = 0;
 
@@ -443,11 +455,25 @@ main(int argc, char *argv[])
       case OPT_QUIET:
        quiet = 1;
        break;
-       
+
       case OPT_GTP_INPUT:
-       gtpfile = gg_optarg;
+      case OPT_GTP_CONNECT:
+      case OPT_GTP_LISTEN:
+       if (gtp_tcp_ip_mode != 0 || gtpfile != NULL) {
+         fprintf(stderr, ("Options `--gtp-input', `--gtp-connect' and 
`--gtp-listen' "
+                          "are mutually-exclusive\n"));
+         exit(EXIT_FAILURE);
+       }
+
+       if (i == OPT_GTP_INPUT)
+         gtpfile = gg_optarg;
+       else {
+         gtp_tcp_ip_mode = i;
+         gtp_tcp_ip_address = gg_optarg;
+       }
+
        break;
-       
+
       case OPT_GTP_DUMP_COMMANDS:
        gtp_dump_commands_file = gg_optarg;
        break;
@@ -1340,29 +1366,69 @@ main(int argc, char *argv[])
     }
 #endif
 
-  case MODE_GTP:  
-    if (gtpfile != NULL) {
-      gtp_input_FILE = fopen(gtpfile, "r");
-      if (gtp_input_FILE == NULL) {
-       fprintf(stderr, "gnugo: Cannot open file %s\n", gtpfile);
-       return EXIT_FAILURE;
-      } 
-    }
-    else
-      gtp_input_FILE = stdin;
+  case MODE_GTP:
+    {
+      FILE *gtp_input_FILE = stdin;
+      FILE *gtp_output_FILE = stdout;
+      FILE *gtp_dump_commands_FILE = NULL;
+
+      if (gtpfile != NULL) {
+       gtp_input_FILE = fopen(gtpfile, "r");
+       if (gtp_input_FILE == NULL) {
+         fprintf(stderr, "gnugo: Cannot open file %s\n", gtpfile);
+         return EXIT_FAILURE;
+       }
+      }
+      else if (gtp_tcp_ip_mode != 0) {
+       unsigned int port = 65536;
+       char *port_string = strchr(gtp_tcp_ip_address, ':');
+       const char *host_name = NULL;
+
+       if (port_string) {
+         host_name = gtp_tcp_ip_address;
 
-    if (gtp_dump_commands_file != NULL) {
-      gtp_dump_commands_FILE = fopen(gtp_dump_commands_file, "w");
-      if (gtp_dump_commands_FILE == NULL) {
-       fprintf(stderr, "gnugo: Cannot open file %s\n",
-               gtp_dump_commands_file);
-       return EXIT_FAILURE;
-      } 
+         *port_string++ = 0;
+         sscanf(port_string, "%u", &port);
+       }
+       else
+         sscanf(gtp_tcp_ip_address, "%u", &port);
+
+       if (port > 65535) {
+         fprintf(stderr, "A valid TCP/IP port number expected\n");
+         exit(EXIT_FAILURE);
+       }
+
+       if (gtp_tcp_ip_mode == OPT_GTP_CONNECT) {
+         socket_connect_to(host_name, port,
+                           &gtp_input_FILE, &gtp_output_FILE);
+       }
+       else {
+         socket_listen_at(host_name, port,
+                          &gtp_input_FILE, &gtp_output_FILE);
+       }
+      }
+
+      if (gtp_dump_commands_file != NULL) {
+       gtp_dump_commands_FILE = fopen(gtp_dump_commands_file, "w");
+       if (gtp_dump_commands_FILE == NULL) {
+         fprintf(stderr, "gnugo: Cannot open file %s\n",
+                 gtp_dump_commands_file);
+         return EXIT_FAILURE;
+       }
+      }
+
+      play_gtp(gtp_input_FILE, gtp_output_FILE, gtp_dump_commands_FILE,
+              orientation);
+
+      if (gtp_dump_commands_FILE)
+       fclose(gtp_dump_commands_FILE);
+
+      if (gtp_tcp_ip_mode == OPT_GTP_CONNECT)
+       socket_close_connection(gtp_input_FILE, gtp_output_FILE);
+      else if (gtp_tcp_ip_mode == OPT_GTP_LISTEN)
+       socket_stop_listening(gtp_input_FILE, gtp_output_FILE);
     }
 
-    play_gtp(gtp_input_FILE, gtp_dump_commands_FILE, orientation);
-    if (gtp_dump_commands_FILE)
-      fclose(gtp_dump_commands_FILE);
     break;
 
   case MODE_ASCII_EMACS:  
@@ -1435,8 +1501,14 @@ Main Options:\n\
        --quiet           Don't print copyright and informational messages\n\
        --level <amount>  strength (default %d)\n\
        --never-resign    Forbid GNU Go to resign\n\
-       --resign-allowed         Allow resignation (default)\n\
+       --resign-allowed  Allow resignation (default)\n\
        --gtp-input <file>Read gtp commands from file instead of stdin\n\
+       --gtp-connect [HOST:]PORT\n\
+                         Connect to given host (127.0.0.1 if omitted) and 
port\n\
+                         and receive GTP commands on the established 
connection\n\
+       --gtp-listen [HOST:]PORT\n\
+                         Wait for the first TCP/IP connection on the given 
port\n\
+                         (if HOST is specified, only to that host)\n\
    -l, --infile <file>   Load name sgf file\n\
    -L, --until <move>    Stop loading just before move is played. <move>\n\
                          can be the move number or location (eg L10).\n\
@@ -1628,6 +1700,206 @@ show_copyright(void)
 }
 
 
+#if ENABLE_SOCKET_SUPPORT
+
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+
+static void
+socket_connect_to(const char *host_name, unsigned int port,
+                 FILE **input_file, FILE **output_file)
+{
+  struct sockaddr_in address;
+  int connection_socket;
+  struct hostent *host_data;
+  char **address_pointer;
+
+  if (!host_name)
+    host_name = "127.0.0.1";
+
+  host_data = gethostbyname(host_name);
+  if (!host_data
+      || host_data->h_addrtype != AF_INET
+      || host_data->h_length != sizeof address.sin_addr) {
+    fprintf(stderr, "Failed to resolve host name `%s'\n", host_name);
+    exit(EXIT_FAILURE);
+  }
+
+  connection_socket = socket(PF_INET, SOCK_STREAM, 0);
+  if (connection_socket == -1) {
+    fprintf(stderr, "Unexpected error: failed to create a socket\n");
+    exit(EXIT_FAILURE);
+  }
+
+  address.sin_family = AF_INET;
+  address.sin_port = htons(port);
+
+  for (address_pointer = host_data->h_addr_list; *address_pointer;
+       address_pointer++) {
+    memcpy(&address.sin_addr, *address_pointer, sizeof address.sin_addr);
+    if (connect(connection_socket, (struct sockaddr *) &address,
+               sizeof address) != -1)
+      break;
+  }
+
+  if (! *address_pointer) {
+    fprintf(stderr, "Failed to connect to %s:%d\n", host_data->h_name, port);
+    close(connection_socket);
+    exit(EXIT_FAILURE);
+  }
+
+  *input_file  = fdopen(connection_socket, "r");
+  *output_file = fdopen(dup(connection_socket), "w");
+}
+
+
+static void
+socket_listen_at(const char *host_name, unsigned int port,
+                FILE **input_file, FILE **output_file)
+{
+  struct sockaddr_in address;
+  int listening_socket;
+  int connection_socket;
+
+  if (host_name) {
+    struct hostent *host_data;
+
+    host_data = gethostbyname(host_name);
+    if (!host_data
+       || host_data->h_addrtype != AF_INET
+       || host_data->h_length != sizeof address.sin_addr) {
+      fprintf(stderr, "Failed to resolve host name `%s'\n", host_name);
+      exit(EXIT_FAILURE);
+    }
+
+    host_name = host_data->h_name;
+    memcpy(&address.sin_addr, host_data->h_addr_list[0],
+          sizeof address.sin_addr);
+  }
+  else
+    address.sin_addr.s_addr = htonl(INADDR_ANY);
+
+  listening_socket = socket(PF_INET, SOCK_STREAM, 0);
+  if (listening_socket == -1) {
+    fprintf(stderr, "Unexpected error: failed to create a socket\n");
+    exit(EXIT_FAILURE);
+  }
+
+  address.sin_family = AF_INET;
+  address.sin_port = htons(port);
+
+  if (verbose) {
+    if (host_name) {
+      fprintf(stderr, "Waiting for a connection on %s:%d...\n",
+             host_name, port);
+    }
+    else
+      fprintf(stderr, "Waiting for a connection on port %d...\n", port);
+  }
+
+  if (bind(listening_socket,
+          (struct sockaddr *) &address, sizeof address) == -1
+      || listen(listening_socket, 0) == -1
+      || (connection_socket = accept(listening_socket, NULL, NULL)) == -1) {
+    if (host_name)
+      fprintf(stderr, "Failed to listen on %s:%d\n", host_name, port);
+    else
+      fprintf(stderr, "Failed to listen on port %d\n", port);
+
+    close(listening_socket);
+    exit(EXIT_FAILURE);
+  }
+
+  close(listening_socket);
+
+  *input_file  = fdopen(connection_socket, "r");
+  *output_file = fdopen(dup(connection_socket), "w");
+}
+
+
+static void
+socket_close_connection(FILE *input_file, FILE *output_file)
+{
+  /* When connecting, we close the socket first. */
+  fclose(input_file);
+  fclose(output_file);
+}
+
+
+static void
+socket_stop_listening(FILE *input_file, FILE *output_file)
+{
+  int buffer[0x1000];
+
+  if (verbose)
+    fprintf(stderr, "Waiting for the client to disconnect...\n");
+
+  /* When listening, we wait for the client to disconnect first.
+   * Otherwise, socket doesn't get released properly.
+   */
+  do
+    fread(buffer, sizeof buffer, 1, input_file);
+  while (!feof(input_file));
+
+  fclose(input_file);
+  fclose(output_file);
+}
+
+
+#else  /* not ENABLE_SOCKET_SUPPORT */
+
+
+static void
+socket_connect_to(const char *host_name, unsigned int port,
+                 FILE **input_file, FILE **output_file)
+{
+  UNUSED(host_name);
+  UNUSED(port);
+  UNUSED(input_file);
+  UNUSED(output_file);
+
+  fprintf(stderr, "GNU Go was compiled without socket support, unable to 
connect\n");
+  exit(EXIT_FAILURE);
+}
+
+
+static void
+socket_listen_at(const char *host_name, unsigned int port,
+                FILE **input_file, FILE **output_file)
+{
+  UNUSED(host_name);
+  UNUSED(port);
+  UNUSED(input_file);
+  UNUSED(output_file);
+
+  fprintf(stderr, "GNU Go was compiled without socket support, unable to 
listen\n");
+  exit(EXIT_FAILURE);
+}
+
+
+static void
+socket_close_connection(FILE *input_file, FILE *output_file)
+{
+  UNUSED(input_file);
+  UNUSED(output_file);
+}
+
+
+static void
+socket_stop_listening(FILE *input_file, FILE *output_file)
+{
+  UNUSED(input_file);
+  UNUSED(output_file);
+}
+
+
+#endif /* not ENABLE_SOCKET_SUPPORT */
+
+
 /*
  * Local Variables:
  * tab-width: 8
Index: interface/play_gtp.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/play_gtp.c,v
retrieving revision 1.153
diff -u -p -r1.153 play_gtp.c
--- interface/play_gtp.c        19 Jul 2004 12:23:09 -0000      1.153
+++ interface/play_gtp.c        10 Oct 2004 14:59:57 -0000
@@ -337,12 +337,15 @@ static struct gtp_command commands[] = {
 
 /* Start playing using the Go Text Protocol. */
 void
-play_gtp(FILE *gtp_input, FILE *gtp_dump_commands, int gtp_initial_orientation)
+play_gtp(FILE *gtp_input, FILE *gtp_output, FILE *gtp_dump_commands,
+        int gtp_initial_orientation)
 {
-  /* Make sure stdout is unbuffered. (Line buffering is also okay but
-   * not necessary. Block buffering breaks GTP mode.)
+  /* Make sure `gtp_output' is unbuffered. (Line buffering is also
+   * okay but not necessary. Block buffering breaks GTP mode.)
+   *
+   * FIXME: Maybe should go to `gtp.c'?
    */
-  setbuf(stdout, NULL);
+  setbuf(gtp_output, NULL);
 
   /* Inform the GTP utility functions about the board size. */
   gtp_internal_set_boardsize(board_size);
@@ -355,7 +358,7 @@ play_gtp(FILE *gtp_input, FILE *gtp_dump
   /* Prepare pattern matcher and reading code. */
   reset_engine();
   clearstats();
-  gtp_main_loop(commands, gtp_input, gtp_dump_commands);
+  gtp_main_loop(commands, gtp_input, gtp_output, gtp_dump_commands);
   if (showstatistics)
     showstats();
 }
@@ -2633,7 +2636,7 @@ gtp_move_reasons(char *s)
     return gtp_failure("vertex must not be occupied");
 
   gtp_start_response(GTP_SUCCESS);
-  if (list_move_reasons(stdout, POS(i, j)) == 0)
+  if (list_move_reasons(gtp_output_file, POS(i, j)) == 0)
     gtp_printf("\n");
   gtp_printf("\n");
   return GTP_OK;
@@ -2653,7 +2656,7 @@ gtp_all_move_values(char *s)
 {
   UNUSED(s);
   gtp_start_response(GTP_SUCCESS);
-  print_all_move_values();
+  print_all_move_values(gtp_output_file);
   gtp_printf("\n");
   return GTP_OK;
 }
@@ -3562,7 +3565,7 @@ gtp_showboard(char *s)
   
   gtp_start_response(GTP_SUCCESS);
   gtp_printf("\n");
-  simple_showboard(stdout);
+  simple_showboard(gtp_output_file);
   return gtp_finish_response();
 }
 
@@ -4015,7 +4018,7 @@ gtp_dragon_data(char *s)
                && dragon[POS(m, n)].origin == POS(m, n))) {
          gtp_print_vertex(m, n);
          gtp_printf(":\n");
-         report_dragon(stdout, POS(m, n));
+         report_dragon(gtp_output_file, POS(m, n));
        }
   }
   gtp_printf("\n");
@@ -4281,7 +4284,7 @@ static int
 gtp_echo_err(char *s)
 {
   fprintf(stderr, "%s", s);
-  fflush(stdout);
+  fflush(gtp_output_file);
   fflush(stderr);
   return gtp_success("%s", s);
 }





reply via email to

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