Naum wrote:I am still not sure, but it seems that PeekNamedPipe can't be reliably used to check if there is something waiting in the input buffer used by fgets.
In order for your fgets() to work properly you are probably disabling the buffering (by calling setbuf and setvbuf).
I think that using the Win APIs only is safer then mixing the WinAPI and c runtime library functions.
You could replace the fgets() with something like:
WaitForSingleObject(hInput, INFINITE); // Waits until there is input available
ReadFile(hInput, buffer, length, &numRead);
hInput is the handle to stdin you use in your PeekNamedPipe call.
The only difference is that ReadFile works in the same way as _read() and not like fgets(), so you would have to do more coding to handle the new-line characters.
All this stuff is already implemented in Alessandro's free source.
Alex
I do not know if it cannot be safely used but I know that movei never lose on time in Leo's games
I do not have setbuf or setvbuf in movei.
In games under winboard there are rare cases that movei lose on time in the first move but it never lose on time in the middle of the game and in case of probability of even 0.01% not to get input from winboard I could expect it to lose on time in the middle of the game because of not getting the opponent move.
This may be thanks to the fact that I use some good code that dieter(programmer of yace suggested)
I remember some discussion from CCC when hyatt said also that it is not safe when later I understood that some code of dieter made it safe but this discussion is many months ago and I do not remember it now.
Here is the code that I use.
comments from dieter
static int is_pipe;
static HANDLE input_handle;
/* Call once at startup. thanks to Dieter for this function and the
same for input_available*/
void input_init(void)
{
DWORD dw;
input_handle = GetStdHandle(STD_INPUT_HANDLE);
is_pipe = !GetConsoleMode(input_handle, &dw);
}
int input_available(void)
{
DWORD nchars;
/* When using Standard C input functions, also check if there
is anything in the buffer. After a call to such functions,
the input waiting in the pipe will be copied to the buffer,
and the call to PeekNamedPipe can indicate no input available.
Setting stdin to unbuffered was not enough, IIRC */
if (stdin->_cnt > 0)
{
return 1;
}
if (is_pipe)
{
/* When running under a GUI, you will end here. */
if (!PeekNamedPipe(input_handle, NULL, 0, NULL, &nchars, NULL))
return 1;
/* Something went wrong. Probably the parent program exited.
Could call exit() here. Returning 1 will make the next call
to the input function return EOF, where this should be
catched then. */
return nchars != 0;
}
else
if (nodes&Nodes_Frequency)
return 0;
else
return _kbhit(); /* In "text-mode" without GUI */
}
Uri