提交 75dd6c1a 编写于 作者: M Matt Caswell

Fix s_client/s_server waiting for stdin on Windows

On Windows we were using the function _kbhit() to determine whether there
was input waiting in stdin for us to read. Actually all this does is work
out whether there is a keyboard press event waiting to be processed in the
input buffer. This only seems to work in a standard Windows console (not
Msys console) and also doesn't work if you redirect the input from some
other source (as we do in TLSProxy tests). This commit changes things to
work differently depending on whether we are on the Windows console or not.

RT#4255
Reviewed-by: NRichard Levitte <levitte@openssl.org>
上级 384f08dc
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
*/ */
# define _POSIX_C_SOURCE 2 # define _POSIX_C_SOURCE 2
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
...@@ -41,7 +42,7 @@ ...@@ -41,7 +42,7 @@
#endif #endif
#include <openssl/bn.h> #include <openssl/bn.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include "s_apps.h"
#include "apps.h" #include "apps.h"
#ifdef _WIN32 #ifdef _WIN32
...@@ -2550,3 +2551,31 @@ void wait_for_async(SSL *s) ...@@ -2550,3 +2551,31 @@ void wait_for_async(SSL *s)
select(width, (void *)&asyncfds, NULL, NULL, NULL); select(width, (void *)&asyncfds, NULL, NULL, NULL);
#endif #endif
} }
/* if OPENSSL_SYS_WINDOWS is defined then so is OPENSSL_SYS_MSDOS */
#if defined(OPENSSL_SYS_MSDOS)
int has_stdin_waiting(void)
{
# if defined(OPENSSL_SYS_WINDOWS)
HANDLE inhand = GetStdHandle(STD_INPUT_HANDLE);
DWORD events = 0;
INPUT_RECORD inputrec;
DWORD insize = 1;
BOOL peeked;
if (inhand == INVALID_HANDLE_VALUE) {
return 0;
}
peeked = PeekConsoleInput(inhand, &inputrec, insize, &events);
if (!peeked) {
/* Probably redirected input? _kbhit() does not work in this case */
if (!feof(stdin)) {
return 1;
}
return 0;
}
# endif
return _kbhit();
}
#endif
...@@ -67,6 +67,9 @@ CONF *app_load_config_quiet(const char *filename); ...@@ -67,6 +67,9 @@ CONF *app_load_config_quiet(const char *filename);
int app_load_modules(const CONF *config); int app_load_modules(const CONF *config);
void unbuffer(FILE *fp); void unbuffer(FILE *fp);
void wait_for_async(SSL *s); void wait_for_async(SSL *s);
# if defined(OPENSSL_SYS_MSDOS)
int has_stdin_waiting(void);
# endif
/* /*
* Common verification options. * Common verification options.
......
...@@ -2160,18 +2160,8 @@ int s_client_main(int argc, char **argv) ...@@ -2160,18 +2160,8 @@ int s_client_main(int argc, char **argv)
tv.tv_usec = 0; tv.tv_usec = 0;
i = select(width, (void *)&readfds, (void *)&writefds, i = select(width, (void *)&readfds, (void *)&writefds,
NULL, &tv); NULL, &tv);
# if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS) if (!i && (!has_stdin_waiting() || !read_tty))
if (!i && (!_kbhit() || !read_tty))
continue; continue;
# else
if (!i && (!((_kbhit())
|| (WAIT_OBJECT_0 ==
WaitForSingleObject(GetStdHandle
(STD_INPUT_HANDLE),
0)))
|| !read_tty))
continue;
# endif
} else } else
i = select(width, (void *)&readfds, (void *)&writefds, i = select(width, (void *)&readfds, (void *)&writefds,
NULL, timeoutp); NULL, timeoutp);
...@@ -2348,14 +2338,9 @@ int s_client_main(int argc, char **argv) ...@@ -2348,14 +2338,9 @@ int s_client_main(int argc, char **argv)
/* break; */ /* break; */
} }
} }
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) /* OPENSSL_SYS_MSDOS includes OPENSSL_SYS_WINDOWS */
# if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS) #if defined(OPENSSL_SYS_MSDOS)
else if (_kbhit()) else if (has_stdin_waiting())
# else
else if ((_kbhit())
|| (WAIT_OBJECT_0 ==
WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
# endif
#else #else
else if (FD_ISSET(fileno(stdin), &readfds)) else if (FD_ISSET(fileno(stdin), &readfds))
#endif #endif
......
...@@ -2167,10 +2167,10 @@ static int sv_body(int s, int stype, unsigned char *context) ...@@ -2167,10 +2167,10 @@ static int sv_body(int s, int stype, unsigned char *context)
tv.tv_sec = 1; tv.tv_sec = 1;
tv.tv_usec = 0; tv.tv_usec = 0;
i = select(width, (void *)&readfds, NULL, NULL, &tv); i = select(width, (void *)&readfds, NULL, NULL, &tv);
if ((i < 0) || (!i && !_kbhit())) if (has_stdin_waiting())
continue;
if (_kbhit())
read_from_terminal = 1; read_from_terminal = 1;
if ((i < 0) || (!i && !read_from_terminal))
continue;
#else #else
if ((SSL_version(con) == DTLS1_VERSION) && if ((SSL_version(con) == DTLS1_VERSION) &&
DTLSv1_get_timeout(con, &timeout)) DTLSv1_get_timeout(con, &timeout))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册