ref: 67b2ebda49f691acfd676bb5f662e4e7e5471000
parent: dfe2721a76eddfc50fe3a2e8c80b63b522a4c182
author: Matthew Flatt <mflatt@racket-lang.org>
date: Thu Dec 1 11:09:29 CST 2022
support non-blocking input on Windows for non-consoles Related to #11
--- a/zuo-doc/lang-zuo.scrbl
+++ b/zuo-doc/lang-zuo.scrbl
@@ -1007,6 +1007,8 @@
than @racket[amount] but at least one byte. The result can be an empty
string only if @racket[amount] is @racket[0] or @racket['avail].
+On Windows, @racket['avail] mode is not supported for console input.
+
@history[#:changed "1.5" @elem{Report @racket[eof] when available in @racket['avail] mode.}]}
@defproc[(fd-write [handle handle?] [str string?]) void?]{
--- a/zuo.c
+++ b/zuo.c
@@ -4148,9 +4148,10 @@
static zuo_t *zuo_drain(zuo_raw_handle_t fd, zuo_int_t amount) {
/* amount as -1 => read until EOF
- amount as -2 => non-blocking read on Unix */
+ amount as -2 => non-blocking read */
zuo_t *s;
zuo_int_t sz = 256, offset = 0;
+ int nonblock = (amount == -2);
if ((amount >= 0) && (sz > amount))
sz = amount;
@@ -4162,7 +4163,7 @@
if (amt > 4096) amt = 4096;
#ifdef ZUO_UNIX
{
- int nonblock = (amount == -2), old_fl, r;
+ int old_fl, r;
if (nonblock) {
EINTR_RETRY(old_fl = fcntl(fd, F_GETFL, 0));
@@ -4186,6 +4187,24 @@
}
#endif
#ifdef ZUO_WINDOWS
+ if (nonblock) {
+ DWORD type = GetFileType(fd);
+ if (type == FILE_TYPE_CHAR)
+ zuo_fail("non-blocking reads are not supported for a console");
+ if (type == FILE_TYPE_PIPE) {
+ DWORD avail;
+ ZUO_STRING_PTR(s)[offset] = 0;
+ ZUO_STRING_LEN(s) = offset;
+ if (!PeekNamedPipe(fd, NULL, 0, NULL, &avail, NULL)) {
+ if (GetLastError() == ERROR_BROKEN_PIPE)
+ return z.o_eof;
+ zuo_fail("error checking pipe");
+ }
+ if (avail == 0)
+ return s;
+ }
+ }
+
{
DWORD dgot;
if (!ReadFile(fd, ZUO_STRING_PTR(s) + offset, amt, &dgot, NULL)) {
@@ -4491,14 +4510,9 @@
zuo_fail_arg(who, "open input file descriptor", fd_h);
if (amount != z.o_eof) {
if ((amount->tag == zuo_symbol_tag)
- && (amount == zuo_symbol("avail"))) {
-#ifdef ZUO_UNIX
+ && (amount == zuo_symbol("avail")))
amt = -2;
-#endif
-#ifdef ZUO_WINDOWS
- zuo_fail1w(who, "non-blocking reads are not supported for file descriptor", fd_h);
-#endif
- } else if ((amount->tag == zuo_integer_tag)
+ else if ((amount->tag == zuo_integer_tag)
&& (ZUO_INT_I(amount) >= 0))
amt = ZUO_INT_I(amount);
else