void setlinebuf(FILE *stream);
Dan,
You might prefer to use the setlinebuf call.
setlinebuf(stdout);
This makes all printf's to stdout flush whenever a \n is encountered, makes the code a little nicer and covers your butt if you forget somewhere to use fflush.
Don
Date: Tue, 28 Aug 2001 11:30:05 -0700 X-Authentication-Warning: match.Stanford.EDU: bump set sender to bump@match.Stanford.EDU using -f From: Daniel Bump bump@match.stanford.edu CC: gnugo@gnu.org, gtp@lists.lysator.liu.se Content-Type: text Content-Length: 2759
Thanks, David, now it's working.
After I saw your message I added fflush(stdout) after the printf to gnugo.
That isn't the first thing I tried but I don't really want to tell everyone how stupid I was. But now that I've rebooted my computer ...
This may have fixed the other problem too which was apparently caused by the EOF that comes down stdin when you type a ^D (one way to terminate metamachine) not getting flushed. Unclear, but I don't have a lingering gnugo process this time.
The current (working) version looks like this.
Dan
#include <stdio.h> #include <unistd.h>
void error(const char *msg);
/* This program uses two pipes to communicate with the * GNU Go client. To an external client it appears to * be a gtp engine. It accomplishes this by intercepting * gtp commands and passing them on to GNU Go. * * This program in and of itself is not useful but it * can be the basis of useful programs. Example: hack * in gmp.c and get a gtp / gmp translator. * * Pipe a: client --> gnugo * Pipe b: gnugo --> client */
int main() { int pfd_a[2]; int pfd_b[2]; char gnugo_line[128], client_line[128]; int length = 0; FILE *to_gnugo_stream, *from_gnugo_stream;
if (pipe(pfd_a) == -1) error("can't open pipe a"); if (pipe(pfd_b) == -1) error("can't open pipe b"); switch(fork()) { case -1: error("fork failed (try chopsticks)"); case 0: /* Attach pipe a to stdin */ if (close(0) == -1) error("close(0) failed"); if (dup(pfd_a[0]) != 0) error("dup pfd_a[0] failed"); /* attach pipe b to stdout" */ if (close(1) == -1) error("close(1) failed"); if (dup(pfd_b[1]) != 1) error("dup pfd_b[1] failed"); execlp("gnugo", "gnugo", "--mode", "gtp", "--quiet", NULL); error("execlp failed"); } /* We use stderr to communicate with the client since stdout is needed. */ /* Attach pipe a to to_gnugo_stream */ to_gnugo_stream = fdopen(pfd_a[1], "w"); /* Attach pipe b to from_gnugo_stream */ from_gnugo_stream = fdopen(pfd_b[0], "r");
while (1) { int length = 0;
if (!fgets(client_line, 128, stdin)) error("can't get command\n"); if (!strncmp(client_line, "quit", 4)) { fprintf(to_gnugo_stream, "%s", "quit\n"); fflush(to_gnugo_stream); return 1; }
if (fprintf(to_gnugo_stream, "%s", client_line) < 0) error("can't write command to to_gnugo_stream"); fflush(to_gnugo_stream); while (length != 1) { if (!fgets(gnugo_line, 128, from_gnugo_stream)) error("can't get response"); length = strlen(gnugo_line); printf(gnugo_line); fflush(stdout); } } }
void error(const char *msg) { fprintf(stderr, "metamachine: %s\n", msg); abort(); }