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