Updated README: Equal sign not required with `--mode` flag.
[sgk-go] / utils / winsocket.c
CommitLineData
7eeb782e
AT
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2 * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
3 * http://www.gnu.org/software/gnugo/ for more information. *
4 * *
5 * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
6 * 2008 and 2009 by the Free Software Foundation. *
7 * *
8 * This program is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU General Public License as *
10 * published by the Free Software Foundation - version 3 or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License in file COPYING for more details. *
17 * *
18 * You should have received a copy of the GNU General Public *
19 * License along with this program; if not, write to the Free *
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
21 * Boston, MA 02111, USA. *
22\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
23
24/* Workaround M$ Windows C library deficiency: it cannot handle
25 * sockets as stdio streams. So we do this ourselves, more or less.
26 *
27 * Call winsocket_activate(...) with socket handle to use. After this
28 * fake stream NULL will work over the socket, while other streams
29 * will (hopefully) keep working as usual.
30 */
31
32#define WINSOCKET_H_INTERNAL_INCLUSION
33
34#include "winsocket.h"
35
36
37#if USE_WINDOWS_SOCKET_CLUDGE
38
39
40#include <assert.h>
41#include <stdarg.h>
42#include <stdio.h>
43#include <string.h>
44
45#include <winsock.h>
46
47
48static int socket_handle = 0;
49static int socket_end_of_file = 0;
50
51
52void
53winsocket_activate(int _socket_handle)
54{
55 assert(socket_handle == 0);
56 socket_handle = _socket_handle;
57}
58
59
60/* Miscellaneous functions. */
61
62void
63winsocket_setbuf(FILE *file, char *buffer)
64{
65 if (file != NULL)
66 setbuf(file, buffer);
67 else
68 assert(socket_handle != 0);
69}
70
71
72int
73winsocket_fflush(FILE *file)
74{
75 if (file != NULL)
76 return fflush(file);
77 else {
78 assert(socket_handle != 0);
79 return 0;
80 }
81}
82
83
84int
85winsocket_feof(FILE *file)
86{
87 if (file != NULL)
88 return feof(file);
89 else {
90 assert(socket_handle != 0);
91 return socket_end_of_file;
92 }
93}
94
95
96int
97winsocket_fclose(FILE *file)
98{
99 if (file != NULL)
100 return fclose(file);
101 else {
102 assert(socket_handle != 0);
103 return 0;
104 }
105}
106
107
108/* Input functions. */
109
110size_t
111winsocket_fread(void *buffer, size_t size, size_t num_items, FILE *file)
112{
113 if (file != NULL)
114 return fread(buffer, size, num_items, file);
115 else {
116 assert(socket_handle != 0);
117 if (recv(socket_handle, (char *) buffer, size * num_items, 0)
118 == size * num_items)
119 return num_items;
120 else {
121 socket_end_of_file = 1;
122 return EOF;
123 }
124 }
125}
126
127
128char *
129winsocket_fgets(char *buffer, int size, FILE *file)
130{
131 if (file != NULL)
132 return fgets(buffer, size, file);
133 else {
134 /* FIXME: Optimize if reading char-by-char is too slow. */
135 int stored_length;
136
137 for (stored_length = 0; stored_length < size - 1; stored_length) {
138 if (recv(socket_handle, buffer + stored_length, 1, 0) != 1) {
139 socket_end_of_file = 1;
140 break;
141 }
142
143 if (buffer[stored_length++] == '\n')
144 break;
145 }
146
147 if (stored_length == 0)
148 return NULL;
149
150 buffer[stored_length + 1] = 0;
151 return buffer;
152 }
153}
154
155
156/* Output functions. */
157
158size_t
159winsocket_fwrite(const void *buffer, size_t size, size_t num_items,
160 FILE *file)
161{
162 if (file != NULL)
163 return fwrite(buffer, size, num_items, file);
164 else {
165 assert(socket_handle != 0);
166 return ((send(socket_handle, (const char *) buffer, size * num_items, 0)
167 == size * num_items)
168 ? num_items : EOF);
169 }
170}
171
172
173int
174winsocket_fputc(int character, FILE *file)
175{
176 if (file != NULL)
177 return fputc(character, file);
178 else {
179 assert(socket_handle != 0);
180 return (send(socket_handle, (const char *) &character, 1, 0) == 1
181 ? character : EOF);
182 }
183}
184
185
186int
187winsocket_fputs(const char *string, FILE *file)
188{
189 if (file != NULL)
190 return fputs(string, file);
191 else {
192 int length = strlen(string);
193
194 assert(socket_handle != 0);
195 return send(socket_handle, string, length, 0) == length ? length : EOF;
196 }
197}
198
199
200int
201winsocket_fprintf(FILE *file, const char *format_string, ...)
202{
203 va_list arguments;
204 int result;
205
206 va_start(arguments, format_string);
207 result = winsocket_vfprintf(file, format_string, arguments);
208 va_end(arguments);
209
210 return result;
211}
212
213
214int
215winsocket_vfprintf(FILE *file, const char *format_string, va_list arguments)
216{
217 if (file != NULL)
218 return vfprintf(file, format_string, arguments);
219 else {
220 char buffer[0x1000];
221 int length = _vsnprintf(buffer, sizeof buffer, format_string, arguments);
222
223 assert(socket_handle != 0);
224 return send(socket_handle, buffer, length, 0) == length ? length : -1;
225 }
226}
227
228
229#endif /* USE_WINDOWS_SOCKET_CLUDGE */
230
231
232/*
233 * Local Variables:
234 * tab-width: 8
235 * c-basic-offset: 2
236 * End:
237 */