Piotr Caban : msvcrt: Support NULL buffer in setvbuf.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jun 26 15:04:51 CDT 2014


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

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Thu Jun 26 12:29:59 2014 +0200

msvcrt: Support NULL buffer in setvbuf.

---

 dlls/msvcrt/file.c       | 53 ++++++++++++++++++++++++++++++------------------
 dlls/msvcrt/msvcrt.h     |  1 +
 dlls/msvcrt/tests/file.c |  4 ++++
 3 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index fe2d144..465a417 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -4478,26 +4478,39 @@ int CDECL MSVCRT__wrename(const MSVCRT_wchar_t *oldpath,const MSVCRT_wchar_t *ne
  */
 int CDECL MSVCRT_setvbuf(MSVCRT_FILE* file, char *buf, int mode, MSVCRT_size_t size)
 {
-  MSVCRT__lock_file(file);
-  if(file->_bufsiz) {
-	if(file->_flag & MSVCRT__IOMYBUF)
-		MSVCRT_free(file->_base);
-	file->_flag &= ~MSVCRT__IOMYBUF;
-	file->_base = file->_ptr = NULL;
-	file->_bufsiz = 0;
-	file->_cnt = 0;
-  }
-  if(mode == MSVCRT__IOFBF) {
-	file->_flag &= ~MSVCRT__IONBF;
-  	file->_base = file->_ptr = buf;
-  	if(buf) {
-		file->_bufsiz = size;
-	}
-  } else {
-	file->_flag |= MSVCRT__IONBF;
-  }
-  MSVCRT__unlock_file(file);
-  return 0;
+    if(!MSVCRT_CHECK_PMT(file != NULL)) return -1;
+    if(!MSVCRT_CHECK_PMT(mode==MSVCRT__IONBF || mode==MSVCRT__IOFBF || mode==MSVCRT__IOLBF)) return -1;
+    if(!MSVCRT_CHECK_PMT(mode==MSVCRT__IONBF || (size>=2 && size<=INT_MAX))) return -1;
+
+    MSVCRT__lock_file(file);
+
+    MSVCRT_fflush(file);
+    if(file->_flag & MSVCRT__IOMYBUF)
+        MSVCRT_free(file->_base);
+    file->_flag &= ~(MSVCRT__IONBF | MSVCRT__IOMYBUF | MSVCRT__USERBUF);
+    file->_cnt = 0;
+
+    if(mode == MSVCRT__IONBF) {
+        file->_flag |= MSVCRT__IONBF;
+        file->_base = file->_ptr = (char*)&file->_charbuf;
+        file->_bufsiz = 2;
+    }else if(buf) {
+        file->_base = file->_ptr = buf;
+        file->_flag |= MSVCRT__USERBUF;
+        file->_bufsiz = size;
+    }else {
+        file->_base = file->_ptr = malloc(size);
+        if(!file->_base) {
+            file->_bufsiz = 0;
+            MSVCRT__unlock_file(file);
+            return -1;
+        }
+
+        file->_flag |= MSVCRT__IOMYBUF;
+        file->_bufsiz = size;
+    }
+    MSVCRT__unlock_file(file);
+    return 0;
 }
 
 /*********************************************************************
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h
index 22ba0d4..3349c9f 100644
--- a/dlls/msvcrt/msvcrt.h
+++ b/dlls/msvcrt/msvcrt.h
@@ -740,6 +740,7 @@ struct MSVCRT__stat64 {
 #define MSVCRT__IOERR    0x0020
 #define MSVCRT__IOSTRG   0x0040
 #define MSVCRT__IORW     0x0080
+#define MSVCRT__USERBUF  0x0100
 #define MSVCRT__IOCOMMIT 0x4000
 
 #define MSVCRT__S_IEXEC  0x0040
diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c
index 422e41d..2fd46f2 100644
--- a/dlls/msvcrt/tests/file.c
+++ b/dlls/msvcrt/tests/file.c
@@ -144,6 +144,9 @@ static void test_fileops( void )
         fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
         file = fdopen (fd, "rb");
         setvbuf(file,NULL,bufmodes[bufmode],2048);
+        if(bufmodes[bufmode] == _IOFBF)
+            ok(file->_bufsiz == 2048, "file->_bufsiz = %d\n", file->_bufsiz);
+        ok(file->_base != NULL, "file->_base = NULL\n");
         ok(strlen(outbuffer) == (sizeof(outbuffer)-1),"strlen/sizeof error for bufmode=%x\n", bufmodes[bufmode]);
         ok(fgets(buffer,sizeof(buffer),file) !=0,"fgets failed unexpected for bufmode=%x\n", bufmodes[bufmode]);
         ok(fgets(buffer,sizeof(buffer),file) ==0,"fgets didn't signal EOF for bufmode=%x\n", bufmodes[bufmode]);
@@ -629,6 +632,7 @@ static void test_flsbuf( void )
   ok(tempfh->_cnt == 0, "_cnt on freshly opened file was %d\n", tempfh->_cnt);
   setbuf(tempfh, NULL);
   ok(tempfh->_cnt == 0, "_cnt on unbuffered file was %d\n", tempfh->_cnt);
+  ok(tempfh->_bufsiz == 2, "_bufsiz = %d\n", tempfh->_bufsiz);
   /* Inlined putchar sets _cnt to -1.  Native seems to ignore the value... */
   tempfh->_cnt = 1234;
   ret = _flsbuf('Q',tempfh);




More information about the wine-cvs mailing list