238 lines
5.3 KiB
C
238 lines
5.3 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
|
|
* This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
|
|
* http://www.gnu.org/software/gnugo/ for more information. *
|
|
* *
|
|
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
|
|
* 2008 and 2009 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 3 or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* 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., 51 Franklin Street, Fifth Floor, *
|
|
* 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:
|
|
*/
|