Fixes segfault in gnushogi when asking for help.
[gnushogi.git] / gnushogi / sysdeps.c
1 /*
2  * FILE: sysdeps.c
3  *
4  *     System-dependent functions for GNU Shogi.
5  *
6  * ----------------------------------------------------------------------
7  *
8  * Copyright (c) 2012 Free Software Foundation
9  *
10  * GNU SHOGI is based on GNU CHESS
11  *
12  * This file is part of GNU SHOGI.
13  *
14  * GNU Shogi is free software; you can redistribute it and/or modify it
15  * under the terms of the GNU General Public License as published by the
16  * Free Software Foundation; either version 3 of the License,
17  * or (at your option) any later version.
18  *
19  * GNU Shogi is distributed in the hope that it will be useful, but WITHOUT
20  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22  * for more details.
23  *
24  * You should have received a copy of the GNU General Public License along
25  * with GNU Shogi; see the file COPYING. If not, see
26  * <http://www.gnu.org/licenses/>.
27  * ----------------------------------------------------------------------
28  *
29  */
30
31 #include "gnushogi.h"
32
33 #if HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36
37 #if HAVE_SYS_FILIO_H
38 /* Definition of FIONREAD */
39 #include <sys/filio.h>
40 #endif
41
42 #if HAVE_ERRNO_H
43 /* Definition of errno(). */
44 #include <errno.h>
45 #endif
46
47 /* Forward declarations. */
48
49 void ElapsedTime_NOFIONREAD(ElapsedTime_mode iop);
50 void ElapsedTime_FIONREAD(ElapsedTime_mode iop);
51
52
53 /*
54  * Determine the time that has passed since the search was started. If the
55  * elapsed time exceeds the target(ResponseTime + ExtraTime) then set timeout
56  * to true which will terminate the search.
57  * iop = COMPUTE_MODE calculate et, bump ETnodes
58  * iop = COMPUTE_AND_INIT_MODE calculate et, set timeout if time exceeded,
59  *     set reference time
60  */
61
62 /*
63  * ElapsedTime() is actually a wrapper function around the different
64  * versions of ElapsedTime_XXX().  This allows us to compile all the
65  * different ways of measuring time in one executable.
66  */
67
68 void
69 ElapsedTime(ElapsedTime_mode iop)
70 {
71     switch (display_type)
72     {
73     case DISPLAY_RAW:
74         ElapsedTime_NOFIONREAD(iop);
75         break;
76
77     default:
78         ElapsedTime_FIONREAD(iop);
79         break;
80     }
81 }
82
83
84
85 #ifdef HAVE_GETTIMEOFDAY
86 void
87 ElapsedTime_FIONREAD(ElapsedTime_mode iop)
88 {
89     long current_time;
90     int  i;
91     int  nchar;
92
93     struct timeval tv;
94
95     if ((i = ioctl((int) 0, FIONREAD, &nchar)))
96     {
97         perror("FIONREAD");
98         fprintf(stderr,
99                 "You probably have a non-ANSI <ioctl.h>; "
100                 "see README. %d %d %x\n",
101                 i, errno, FIONREAD);
102         exit(1);
103     }
104
105     if (nchar)
106     {
107         if (!flag.timeout)
108             flag.back = true;
109
110         flag.bothsides = false;
111     }
112
113     gettimeofday(&tv, NULL);
114     current_time = tv.tv_sec*100 + (tv.tv_usec/10000);
115
116 #  ifdef INTERRUPT_TEST
117     if (iop == INIT_INTERRUPT_MODE)
118     {
119         itime0 = current_time;
120     }
121     else if (iop == COMPUTE_INTERRUPT_MODE)
122     {
123         it = current_time - itime0;
124     }
125     else
126 #  endif
127     {
128         et = current_time - time0;
129         ETnodes = NodeCnt + znodes;
130
131         if (et < 0)
132         {
133 #  ifdef INTERRUPT_TEST
134             printf("elapsed time %ld not positive\n", et);
135 #  endif
136             et = 0;
137         }
138
139         if (iop == COMPUTE_AND_INIT_MODE)
140         {
141             if ((et > ResponseTime + ExtraTime) && (Sdepth > MINDEPTH))
142                 flag.timeout = true;
143
144             time0 = current_time;
145         }
146
147         if (!NOT_CURSES)
148         {
149 #  ifdef QUIETBACKGROUND
150             if (!background)
151 #  endif /* QUIETBACKGROUND */
152                 UpdateClocks();
153         }
154     }
155 }
156
157
158 void
159 ElapsedTime_NOFIONREAD(ElapsedTime_mode iop)
160 {
161     struct timeval tv;
162     long current_time;
163
164     gettimeofday(&tv, NULL);
165     current_time = tv.tv_sec*100 + (tv.tv_usec/10000);
166
167 #  ifdef INTERRUPT_TEST
168     if (iop == INIT_INTERRUPT_MODE)
169     {
170         itime0 = current_time;
171     }
172     else if (iop == COMPUTE_INTERRUPT_MODE)
173     {
174         it = current_time - itime0;
175     }
176     else
177 #  endif
178     {
179         et = current_time - time0;
180         ETnodes = NodeCnt + znodes;
181
182         if (et < 0)
183         {
184 #  ifdef INTERRUPT_TEST
185             printf("elapsed time %ld not positive\n", et);
186 #  endif
187             et = 0;
188         }
189
190         if (iop == COMPUTE_AND_INIT_MODE)
191         {
192             if ((et > ResponseTime + ExtraTime) && (Sdepth > MINDEPTH))
193                 flag.timeout = true;
194
195             time0 = current_time;
196         }
197
198         if (!NOT_CURSES)
199         {
200 #  ifdef QUIETBACKGROUND
201             if (!background)
202 #  endif /* QUIETBACKGROUND */
203                 UpdateClocks();
204         }
205     }
206 }
207
208
209 #else /* !HAVE_GETTIMEOFDAY */
210
211
212 /*
213  * Determine the time that has passed since the search was started.  If the
214  * elapsed time exceeds the target (ResponseTime + ExtraTime) then set
215  * timeout to true which will terminate the search.
216  *
217  * iop = 0   calculate et, bump ETnodes
218  * iop = 1   calculate et, set timeout if time exceeded, calculate et
219  *
220  */
221
222 void
223 ElapsedTime_FIONREAD(ElapsedTime_mode iop)
224 {
225     long current_time;
226     int  nchar;
227     int  i;
228
229     if ((i = ioctl((int) 0, FIONREAD, &nchar)))
230     {
231         perror("FIONREAD");
232         fprintf(stderr,
233                 "You probably have a non-ANSI <ioctl.h>; "
234                 "see README. %d %d %x\n",
235                 i, errno, FIONREAD);
236         exit(1);
237     }
238
239     if (nchar)
240     {
241         if (!flag.timeout)
242             flag.back = true;
243         flag.bothsides = false;
244     }
245
246     et = ((current_time = time((long *) 0)) - time0) * 100;
247
248 #ifdef INTERRUPT_TEST
249     if (iop == INIT_INTERRUPT_MODE)
250     {
251         itime0 = current_time;
252     }
253     else if (iop == COMPUTE_INTERRUPT_MODE)
254     {
255         it = current_time - itime0;
256     }
257     else
258 #endif
259     {
260         ETnodes = NodeCnt + znodes;
261
262         if (et < 0)
263         {
264 #ifdef INTERRUPT_TEST
265             printf("elapsed time %ld not positive\n", et);
266 #endif
267             et = 0;
268         }
269
270         if (iop == COMPUTE_AND_INIT_MODE)
271         {
272             if ((et > (ResponseTime + ExtraTime)) && (Sdepth > MINDEPTH))
273                 flag.timeout = true;
274
275             time0 = current_time;
276         }
277
278         if (!NOT_CURSES)
279         {
280 #ifdef QUIETBACKGROUND
281             if (!background)
282 #endif /* QUIETBACKGROUND */
283                 UpdateClocks();
284         }
285     }
286 }
287
288
289
290 void
291 ElapsedTime_NOFIONREAD(ElapsedTime_mode iop)
292 {
293     long current_time;
294
295     et = ((current_time = time((long *) 0)) - time0) * 100;
296
297 #ifdef INTERRUPT_TEST
298     if (iop == INIT_INTERRUPT_MODE)
299     {
300         itime0 = current_time;
301     }
302     else if (iop == COMPUTE_INTERRUPT_MODE)
303     {
304         it = current_time - itime0;
305     }
306     else
307 #endif
308     {
309         ETnodes = NodeCnt + znodes;
310
311         if (et < 0)
312         {
313 #ifdef INTERRUPT_TEST
314             printf("elapsed time %ld not positive\n", et);
315 #endif
316             et = 0;
317         }
318
319         if (iop == COMPUTE_AND_INIT_MODE)
320         {
321             if ((et > (ResponseTime + ExtraTime)) && (Sdepth > MINDEPTH))
322                 flag.timeout = true;
323
324             time0 = current_time;
325         }
326
327         if (!NOT_CURSES)
328         {
329 #ifdef QUIETBACKGROUND
330             if (!background)
331 #endif /* QUIETBACKGROUND */
332                 UpdateClocks();
333         }
334     }
335 }
336
337
338 #endif /* HAVE_GETTIMEOFDAY */
339
340
341
342
343