From 56eb6f67305ae390c709adddd114fd9040334135 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Fri, 5 Oct 2007 04:27:08 -0700 Subject: [PATCH] msvcrt: Fix ^Z handling in text mode. --- dlls/msvcrt/file.c | 10 ++++++++-- dlls/msvcrt/tests/file.c | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index b8787810c71..8bacffa8b9d 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -59,6 +59,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); /* values for wxflag in file descriptor */ #define WX_OPEN 0x01 #define WX_ATEOF 0x02 +#define WX_READEOF 0x04 /* like ATEOF, but for underlying file rather than buffer */ #define WX_DONTINHERIT 0x10 #define WX_APPEND 0x20 #define WX_TEXT 0x80 @@ -827,7 +828,7 @@ __int64 CDECL _lseeki64(int fd, __int64 offset, int whence) ofs.QuadPart = offset; if (SetFilePointerEx(hand, ofs, &ret, whence)) { - MSVCRT_fdesc[fd].wxflag &= ~WX_ATEOF; + MSVCRT_fdesc[fd].wxflag &= ~(WX_ATEOF|WX_READEOF); /* FIXME: What if we seek _to_ EOF - is EOF set? */ return ret.QuadPart; @@ -1666,6 +1667,11 @@ static int read_i(int fd, void *buf, unsigned int count) char *bufstart = buf; HANDLE hand = msvcrt_fdtoh(fd); + if (MSVCRT_fdesc[fd].wxflag & WX_READEOF) { + MSVCRT_fdesc[fd].wxflag |= WX_ATEOF; + TRACE("already at EOF, returning 0\n"); + return 0; + } /* Don't trace small reads, it gets *very* annoying */ if (count > 4) TRACE(":fd (%d) handle (%p) buf (%p) len (%d)\n",fd,hand,buf,count); @@ -1692,7 +1698,7 @@ static int read_i(int fd, void *buf, unsigned int count) } if (num_read != count) { - MSVCRT_fdesc[fd].wxflag |= WX_ATEOF; + MSVCRT_fdesc[fd].wxflag |= (WX_ATEOF|WX_READEOF); TRACE(":EOF %s\n",debugstr_an(buf,num_read)); } } diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c index 4a311e4dfa3..e0f1b997e1f 100644 --- a/dlls/msvcrt/tests/file.c +++ b/dlls/msvcrt/tests/file.c @@ -287,6 +287,23 @@ static void test_asciimode(void) ok((fread(buf, 1, sizeof(buf), fp) == 2) && (0 == strcmp(buf, "\r\n")), "CR CR LF not read as CR LF\n"); fclose(fp); unlink("ascii.tst"); + + /* Simple test of foo ^Z [more than one block] bar handling */ + fp = fopen("ascii.tst", "wb"); + fputs("foo\032", fp); /* foo, logical EOF, ... */ + fseek(fp, 65536L, SEEK_SET); /* ... more than MSVCRT_BUFSIZ, ... */ + fputs("bar", fp); /* ... bar */ + fclose(fp); + fp = fopen("ascii.tst", "rt"); + ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets foo\n"); + ok(0 == strcmp(buf, "foo"), "foo ^Z not read as foo by fgets\n"); + ok(fgets(buf, sizeof(buf), fp) == NULL, "fgets after logical EOF\n"); + rewind(fp); + ok((fread(buf, 1, sizeof(buf), fp) == 3) && (0 == strcmp(buf, "foo")), "foo ^Z not read as foo by fread\n"); + ok((fread(buf, 1, sizeof(buf), fp) == 0), "fread after logical EOF\n"); + fclose(fp); + + unlink("ascii.tst"); } static WCHAR* AtoW( const char* p )