Eric Pouech : kernel32: When reading chars out of a bare console, use the Unix API (instead of the Windows one).
Alexandre Julliard
julliard at winehq.org
Mon Dec 13 10:43:20 CST 2010
Module: wine
Branch: master
Commit: 4149643fbe1b3c9c92810fc5cdfc10487e807311
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4149643fbe1b3c9c92810fc5cdfc10487e807311
Author: Eric Pouech <eric.pouech at orange.fr>
Date: Sun Dec 12 22:31:32 2010 +0100
kernel32: When reading chars out of a bare console, use the Unix API (instead of the Windows one).
---
dlls/kernel32/console.c | 56 ++++++++++++++++++++++++++---------------------
1 files changed, 31 insertions(+), 25 deletions(-)
diff --git a/dlls/kernel32/console.c b/dlls/kernel32/console.c
index c0af117..97eae17 100644
--- a/dlls/kernel32/console.c
+++ b/dlls/kernel32/console.c
@@ -41,6 +41,9 @@
#ifdef HAVE_TERMIOS_H
# include <termios.h>
#endif
+#ifdef HAVE_SYS_POLL_H
+# include <sys/poll.h>
+#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -1112,33 +1115,35 @@ static BOOL handle_simple_char(HANDLE conin, unsigned real_inchar)
return WriteConsoleInputW(conin, ir, numEvent, &written);
}
-static enum read_console_input_return bare_console_fetch_input(HANDLE handle, DWORD timeout)
+static enum read_console_input_return bare_console_fetch_input(HANDLE handle, int fd, DWORD timeout)
{
- OVERLAPPED ov;
- enum read_console_input_return ret;
- char ch;
-
- /* get the real handle to the console object */
- handle = wine_server_ptr_handle(console_handle_unmap(handle));
+ struct pollfd pollfd;
+ char ch;
+ enum read_console_input_return ret;
- memset(&ov, 0, sizeof(ov));
- ov.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+ pollfd.fd = fd;
+ pollfd.events = POLLIN;
+ pollfd.revents = 0;
- if (ReadFile(handle, &ch, 1, NULL, &ov) ||
- (GetLastError() == ERROR_IO_PENDING &&
- WaitForSingleObject(ov.hEvent, timeout) == WAIT_OBJECT_0 &&
- GetOverlappedResult(handle, &ov, NULL, FALSE)))
+ switch (poll(&pollfd, 1, timeout))
{
- ret = handle_simple_char(handle, ch) ? rci_gotone : rci_error;
- }
- else
- {
- WARN("Failed read %x\n", GetLastError());
- ret = rci_error;
+ case 1:
+ RtlEnterCriticalSection(&CONSOLE_CritSect);
+ switch (read(fd, &ch, 1))
+ {
+ case 1: ret = handle_simple_char(handle, ch) ? rci_gotone : rci_error; break;
+ /* actually another thread likely beat us to reading the char
+ * return gotone, while not perfect, it should work in most of the cases (as the new event
+ * should be now in the queue)
+ */
+ case 0: ret = rci_gotone; break;
+ default: ret = rci_error; break;
+ }
+ RtlLeaveCriticalSection(&CONSOLE_CritSect);
+ return ret;
+ case 0: return rci_timeout;
+ default: return rci_error;
}
- CloseHandle(ov.hEvent);
-
- return ret;
}
static enum read_console_input_return read_console_input(HANDLE handle, PINPUT_RECORD ir, DWORD timeout)
@@ -1149,12 +1154,13 @@ static enum read_console_input_return read_console_input(HANDLE handle, PINPUT_R
if ((fd = get_console_bare_fd(handle)) != -1)
{
put_console_into_raw_mode(fd);
- close(fd);
if (WaitForSingleObject(GetConsoleInputWaitHandle(), 0) != WAIT_OBJECT_0)
{
- ret = bare_console_fetch_input(handle, timeout);
- if (ret != rci_gotone) return ret;
+ ret = bare_console_fetch_input(handle, fd, timeout);
}
+ else ret = rci_gotone;
+ close(fd);
+ if (ret != rci_gotone) return ret;
}
else
{
More information about the wine-cvs
mailing list