Commit | Line | Data |
---|---|---|
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 | ||
48 | static int socket_handle = 0; | |
49 | static int socket_end_of_file = 0; | |
50 | ||
51 | ||
52 | void | |
53 | winsocket_activate(int _socket_handle) | |
54 | { | |
55 | assert(socket_handle == 0); | |
56 | socket_handle = _socket_handle; | |
57 | } | |
58 | ||
59 | ||
60 | /* Miscellaneous functions. */ | |
61 | ||
62 | void | |
63 | winsocket_setbuf(FILE *file, char *buffer) | |
64 | { | |
65 | if (file != NULL) | |
66 | setbuf(file, buffer); | |
67 | else | |
68 | assert(socket_handle != 0); | |
69 | } | |
70 | ||
71 | ||
72 | int | |
73 | winsocket_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 | ||
84 | int | |
85 | winsocket_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 | ||
96 | int | |
97 | winsocket_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 | ||
110 | size_t | |
111 | winsocket_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 | ||
128 | char * | |
129 | winsocket_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 | ||
158 | size_t | |
159 | winsocket_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 | ||
173 | int | |
174 | winsocket_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 | ||
186 | int | |
187 | winsocket_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 | ||
200 | int | |
201 | winsocket_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 | ||
214 | int | |
215 | winsocket_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 | */ |