Piotr Caban : msvcrt: Fix read() behaviour on "no console" file descriptors.

Alexandre Julliard julliard at winehq.org
Wed Nov 15 16:46:00 CST 2017


Module: wine
Branch: master
Commit: 9b2397d5c87969ce2a3c8dd24e2491b53ee018b1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9b2397d5c87969ce2a3c8dd24e2491b53ee018b1

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed Nov 15 09:47:33 2017 +0100

msvcrt: Fix read() behaviour on "no console" file descriptors.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcrt/file.c       | 20 ++++++++++++++++----
 dlls/msvcrt/tests/file.c | 16 ++++++++++++++++
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index 422e95d..7fcba06 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -2892,6 +2892,7 @@ static int read_i(int fd, ioinfo *fdinfo, void *buf, unsigned int count)
         else
         {
             TRACE(":failed-last error (%d)\n",GetLastError());
+            msvcrt_set_errno(GetLastError());
             return -1;
         }
     }
@@ -2906,8 +2907,16 @@ static int read_i(int fd, ioinfo *fdinfo, void *buf, unsigned int count)
  */
 int CDECL MSVCRT__read(int fd, void *buf, unsigned int count)
 {
-    ioinfo *info = get_ioinfo(fd);
-    int num_read = read_i(fd, info, buf, count);
+    ioinfo *info;
+    int num_read;
+
+    if(fd == MSVCRT_NO_CONSOLE_FD) {
+        *MSVCRT__errno() = MSVCRT_EBADF;
+        return -1;
+    }
+
+    info = get_ioinfo(fd);
+    num_read = read_i(fd, info, buf, count);
     release_ioinfo(info);
     return num_read;
 }
@@ -4291,9 +4300,12 @@ MSVCRT_size_t CDECL MSVCRT__fread_nolock(void *ptr, MSVCRT_size_t size, MSVCRT_s
   {
     int i;
     if (!file->_cnt && rcnt<MSVCRT_BUFSIZ && (file->_flag & (MSVCRT__IOMYBUF | MSVCRT__USERBUF))) {
-      file->_cnt = MSVCRT__read(file->_file, file->_base, file->_bufsiz);
+      i = MSVCRT__read(file->_file, file->_base, file->_bufsiz);
       file->_ptr = file->_base;
-      i = (file->_cnt<rcnt) ? file->_cnt : rcnt;
+      if (i != -1) {
+          file->_cnt = i;
+          if (i > rcnt) i = rcnt;
+      }
       /* If the buffer fill reaches eof but fread wouldn't, clear eof. */
       if (i > 0 && i < file->_cnt) {
         get_ioinfo_nolock(file->_file)->wxflag &= ~WX_ATEOF;
diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c
index 543eb3f..f118ef3 100644
--- a/dlls/msvcrt/tests/file.c
+++ b/dlls/msvcrt/tests/file.c
@@ -1528,6 +1528,7 @@ static void test_invalid_stdin_child( void )
     HANDLE handle;
     ioinfo *info;
     int ret;
+    char c;
 
     errno = 0xdeadbeef;
     handle = (HANDLE)_get_osfhandle(STDIN_FILENO);
@@ -1541,6 +1542,21 @@ static void test_invalid_stdin_child( void )
     ok(stdin->_file == -2, "stdin->_file = %d\n", stdin->_file);
 
     errno = 0xdeadbeef;
+    ret = fread(&c, 1, 1, stdin);
+    ok(!ret, "fread(stdin) returned %d\n", ret);
+    ok(errno == EBADF, "errno = %d\n", errno);
+
+    errno = 0xdeadbeef;
+    ret = read(-2, &c, 1);
+    ok(ret == -1, "read(-2) returned %d\n", ret);
+    ok(errno == EBADF, "errno = %d\n", errno);
+
+    errno = 0xdeadbeef;
+    ret = read(STDIN_FILENO, &c, 1);
+    ok(ret == -1, "read(STDIN_FILENO) returned %d\n", ret);
+    ok(errno == EBADF, "errno = %d\n", errno);
+
+    errno = 0xdeadbeef;
     ret = fclose(stdin);
     ok(ret == -1, "fclose(stdin) returned %d\n", ret);
     ok(errno == EBADF, "errno = %d\n", errno);




More information about the wine-cvs mailing list