msvcrt: Support NULL buffer in setvbuf.

This commit is contained in:
Piotr Caban 2014-06-26 12:29:59 +02:00 committed by Alexandre Julliard
parent 1ae475dae8
commit 18a416f7d5
3 changed files with 38 additions and 20 deletions

View File

@ -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) int CDECL MSVCRT_setvbuf(MSVCRT_FILE* file, char *buf, int mode, MSVCRT_size_t size)
{ {
MSVCRT__lock_file(file); if(!MSVCRT_CHECK_PMT(file != NULL)) return -1;
if(file->_bufsiz) { if(!MSVCRT_CHECK_PMT(mode==MSVCRT__IONBF || mode==MSVCRT__IOFBF || mode==MSVCRT__IOLBF)) return -1;
if(file->_flag & MSVCRT__IOMYBUF) if(!MSVCRT_CHECK_PMT(mode==MSVCRT__IONBF || (size>=2 && size<=INT_MAX))) return -1;
MSVCRT_free(file->_base);
file->_flag &= ~MSVCRT__IOMYBUF; MSVCRT__lock_file(file);
file->_base = file->_ptr = NULL;
file->_bufsiz = 0; MSVCRT_fflush(file);
file->_cnt = 0; if(file->_flag & MSVCRT__IOMYBUF)
} MSVCRT_free(file->_base);
if(mode == MSVCRT__IOFBF) { file->_flag &= ~(MSVCRT__IONBF | MSVCRT__IOMYBUF | MSVCRT__USERBUF);
file->_flag &= ~MSVCRT__IONBF; file->_cnt = 0;
file->_base = file->_ptr = buf;
if(buf) { if(mode == MSVCRT__IONBF) {
file->_bufsiz = size; file->_flag |= MSVCRT__IONBF;
} file->_base = file->_ptr = (char*)&file->_charbuf;
} else { file->_bufsiz = 2;
file->_flag |= MSVCRT__IONBF; }else if(buf) {
} file->_base = file->_ptr = buf;
MSVCRT__unlock_file(file); file->_flag |= MSVCRT__USERBUF;
return 0; 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;
} }
/********************************************************************* /*********************************************************************

View File

@ -740,6 +740,7 @@ struct MSVCRT__stat64 {
#define MSVCRT__IOERR 0x0020 #define MSVCRT__IOERR 0x0020
#define MSVCRT__IOSTRG 0x0040 #define MSVCRT__IOSTRG 0x0040
#define MSVCRT__IORW 0x0080 #define MSVCRT__IORW 0x0080
#define MSVCRT__USERBUF 0x0100
#define MSVCRT__IOCOMMIT 0x4000 #define MSVCRT__IOCOMMIT 0x4000
#define MSVCRT__S_IEXEC 0x0040 #define MSVCRT__S_IEXEC 0x0040

View File

@ -144,6 +144,9 @@ static void test_fileops( void )
fd = open ("fdopen.tst", O_RDONLY | O_BINARY); fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
file = fdopen (fd, "rb"); file = fdopen (fd, "rb");
setvbuf(file,NULL,bufmodes[bufmode],2048); 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(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 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]); 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); ok(tempfh->_cnt == 0, "_cnt on freshly opened file was %d\n", tempfh->_cnt);
setbuf(tempfh, NULL); setbuf(tempfh, NULL);
ok(tempfh->_cnt == 0, "_cnt on unbuffered file was %d\n", tempfh->_cnt); 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... */ /* Inlined putchar sets _cnt to -1. Native seems to ignore the value... */
tempfh->_cnt = 1234; tempfh->_cnt = 1234;
ret = _flsbuf('Q',tempfh); ret = _flsbuf('Q',tempfh);