mvcrt patch
Waldek Hebisch
hebisch at math.uni.wroc.pl
Mon Jan 7 08:58:44 CST 2002
Enclosed is a patch (diff to 2001.12.26 snapshot) which impements
stdio buffering in msvcrt. Since I cannot make Visual C binaries
could anybady with Visual C++ test it?
I have testet it with mingw32 and I incude my test program (iotst.c).
The program prints a line indicating which test it is making
and then complains about failures.
Comment 1: current builtin msvcrt fails test1 (and few other
as a consequence). Some native versions of msvcrt fail test 8.
Comment 2: I wrote the test the way naive programmer would wrote
it (IMHO). Now I think that for a testing framework we need an
assert-like macro to make checking and printing code shorter
and to have uniform printouts. I ommited some tests that require
multiple processes (expandig file while it is read, checking that
stdio buffers got flushed at exit) - I guess that doing such
test in portable way is quite tricky.
--
Waldek Hebisch
hebisch at math.uni.wroc.pl or hebisch at hera.math.uni.wroc.pl
-------------- next part --------------
diff -ru wine-20011226.orig/dlls/msvcrt/file.c wine-20011226/dlls/msvcrt/file.c
--- wine-20011226.orig/dlls/msvcrt/file.c Wed Dec 26 20:50:58 2001
+++ wine-20011226/dlls/msvcrt/file.c Mon Jan 7 14:18:42 2002
@@ -180,6 +180,36 @@
}
}
+/* INTERNAL: Flush stdio file buffer */
+static int msvcrt_flush_buffer(MSVCRT_FILE* file)
+{
+ if(file->_bufsiz) {
+ int cnt=file->_ptr-file->_base;
+ if(cnt>0 && _write(file->_file, file->_base, cnt) != cnt) {
+ return MSVCRT_EOF;
+ }
+ file->_ptr=file->_base;
+ file->_cnt=file->_bufsiz;
+ }
+ return 0;
+}
+
+/* INTERNAL: Allocate stdio file buffer */
+static void msvcrt_alloc_buffer(MSVCRT_FILE* file)
+{
+ file->_base = MSVCRT_calloc(MSVCRT_BUFSIZ,1);
+ if(file->_base) {
+ file->_bufsiz = MSVCRT_BUFSIZ;
+ file->_flag |= MSVCRT__IOMYBUF;
+ } else {
+ file->_base = (unsigned char *)(&file->_charbuf);
+ /* put here 2 ??? */
+ file->_bufsiz = sizeof(file->_charbuf);
+ }
+ file->_ptr = file->_base;
+ file->_cnt = 0;
+}
+
/*********************************************************************
* __p__iob(MSVCRT.@)
*/
@@ -306,6 +336,14 @@
TRACE(":fd (%d) handle (%d)\n",fd,hand);
if (hand == INVALID_HANDLE_VALUE)
return -1;
+ /* flush stdio buffers */
+ if(MSVCRT_files[fd]) {
+ if(MSVCRT_files[fd]->_flag & MSVCRT__IOWRT)
+ MSVCRT_fflush(MSVCRT_files[fd]);
+
+ if(MSVCRT_files[fd]->_flag & MSVCRT__IOMYBUF)
+ MSVCRT_free(MSVCRT_files[fd]->_base);
+ }
/* Dont free std FILE*'s, they are not dynamic */
if (fd > 2 && MSVCRT_files[fd])
@@ -376,7 +414,7 @@
* will be set by the read()/write() functions.
*/
if (MSVCRT_files[fd])
- return MSVCRT_files[fd]->_flag & MSVCRT__IOEOF;
+ return MSVCRT_flags[fd] & MSVCRT__IOEOF;
/* Otherwise we do it the hard way */
curpos = SetFilePointer(hand, 0, NULL, SEEK_CUR);
@@ -458,8 +496,8 @@
void MSVCRT_rewind(MSVCRT_FILE* file)
{
TRACE(":file (%p) fd (%d)\n",file,file->_file);
- _lseek(file->_file,0,SEEK_SET);
- file->_flag &= ~(MSVCRT__IOEOF | MSVCRT__IOERR);
+ MSVCRT_fseek(file, 0L, SEEK_SET);
+ MSVCRT_clearerr(file);
}
/*********************************************************************
@@ -528,10 +566,16 @@
while(i < MSVCRT_fdend)
if (MSVCRT_handles[i] != INVALID_HANDLE_VALUE)
{
+#if 0
+ /* FIXME: flush, do not commit */
if (_commit(i) == -1)
if (MSVCRT_files[i])
MSVCRT_files[i]->_flag |= MSVCRT__IOERR;
- num_flushed++;
+#endif
+ if(MSVCRT_files[i] && MSVCRT_files[i]->_flag & MSVCRT__IOWRT) {
+ MSVCRT_fflush(MSVCRT_files[i]);
+ num_flushed++;
+ }
}
TRACE(":flushed (%d) handles\n",num_flushed);
@@ -905,7 +949,10 @@
if (num_read != count && MSVCRT_files[fd])
{
TRACE(":EOF\n");
+ MSVCRT_flags[fd] |= MSVCRT__IOEOF;
+/*
MSVCRT_files[fd]->_flag |= MSVCRT__IOEOF;
+*/
}
return num_read;
}
@@ -1161,12 +1208,6 @@
if (MSVCRT_flags[fd] & MSVCRT__IOAPPEND)
_lseek(fd, 0, FILE_END);
- /* Set _cnt to 0 so optimised binaries will call our implementation
- * of putc/getc.
- */
- if (MSVCRT_files[fd])
- MSVCRT_files[fd]->_cnt = 0;
-
if (WriteFile(hand, buf, count, &num_written, NULL)
&& (num_written == count))
return num_written;
@@ -1226,7 +1267,13 @@
*/
int MSVCRT_fflush(MSVCRT_FILE* file)
{
- return _commit(file->_file);
+ if(!file) {
+ _flushall();
+ return 0;
+ } else {
+ int res=msvcrt_flush_buffer(file);
+ return res;
+ }
}
/*********************************************************************
@@ -1234,10 +1281,12 @@
*/
int MSVCRT_fgetc(MSVCRT_FILE* file)
{
- char c;
- if (_read(file->_file,&c,1) != 1)
- return MSVCRT_EOF;
- return c;
+ if (file->_cnt>0) {
+ file->_cnt--;
+ return *(unsigned char *)file->_ptr++;
+ } else {
+ return _filbuf(file);
+ }
}
/*********************************************************************
@@ -1253,7 +1302,36 @@
*/
int _filbuf(MSVCRT_FILE* file)
{
- return MSVCRT_fgetc(file);
+
+ /* Allocate buffer if needed */
+ if(file->_bufsiz == 0 && !(file->_flag & MSVCRT__IONBF) ) {
+ msvcrt_alloc_buffer(file);
+ }
+ if(!(file->_flag & MSVCRT__IOREAD)) {
+ if(file->_flag & MSVCRT__IORW) {
+ file->_flag |= MSVCRT__IOREAD;
+ } else {
+ return MSVCRT_EOF;
+ }
+ }
+ if(file->_flag & MSVCRT__IONBF) {
+ unsigned char c;
+ if (_read(file->_file,&c,1) != 1) {
+ file->_flag |= MSVCRT__IOEOF;
+ return MSVCRT_EOF;
+ }
+ return c;
+ } else {
+ file->_cnt = _read(file->_file, file->_base, file->_bufsiz);
+ if(file->_cnt<0) file->_cnt = 0;
+ if(!file->_cnt) {
+ file->_flag |= MSVCRT__IOEOF;
+ return MSVCRT_EOF;
+ }
+ file->_cnt--;
+ file->_ptr = file->_base+1;
+ return *(unsigned char *)file->_base;
+ }
}
/*********************************************************************
@@ -1261,7 +1339,7 @@
*/
int MSVCRT_fgetpos(MSVCRT_FILE* file, MSVCRT_fpos_t *pos)
{
- *pos = _tell(file->_file);
+ *pos = MSVCRT_ftell(file);
return (*pos == -1? -1 : 0);
}
@@ -1305,7 +1383,7 @@
*/
MSVCRT_wint_t MSVCRT_fgetwc(MSVCRT_FILE* file)
{
- MSVCRT_wint_t wc;
+ WCHAR wc;
if (_read(file->_file, &wc, sizeof(wc)) != sizeof(wc))
return MSVCRT_WEOF;
return wc;
@@ -1336,11 +1414,48 @@
}
/*********************************************************************
+ * fgetws (MSVCRT.@)
+ */
+WCHAR *MSVCRT_fgetws(WCHAR *s, int size, MSVCRT_FILE* file)
+{
+ int cc;
+ WCHAR * buf_start = s;
+
+ TRACE(":file(%p) fd (%d) str (%p) len (%d)\n",
+ file,file->_file,s,size);
+
+ /* BAD, for the whole WINE process blocks... just done this way to test
+ * windows95's ftp.exe.
+ * JG - Is this true now we use ReadFile() on stdin too?
+ */
+ for(cc = MSVCRT_fgetwc(file); cc != MSVCRT_WEOF && cc != L'\n';
+ cc = MSVCRT_fgetwc(file))
+ if (cc != L'\r')
+ {
+ if (--size <= 0) break;
+ *s++ = cc;
+ }
+ if ((cc == MSVCRT_EOF) && (s == buf_start)) /* If nothing read, return 0*/
+ {
+ TRACE(":nothing read\n");
+ return 0;
+ }
+ if (cc == L'\n')
+ if (--size > 0)
+ *s++ = '\n';
+ *s = '\0';
+/* TRACE(":got '%s'\n", buf_start); */
+ return buf_start;
+}
+
+
+/*********************************************************************
* fputwc (MSVCRT.@)
*/
MSVCRT_wint_t MSVCRT_fputwc(MSVCRT_wint_t wc, MSVCRT_FILE* file)
{
- if (_write(file->_file, &wc, sizeof(wc)) != sizeof(wc))
+ WCHAR mwc=wc;
+ if (MSVCRT_fwrite( &mwc, 1, sizeof(mwc), file) != sizeof(mwc))
return MSVCRT_WEOF;
return wc;
}
@@ -1463,7 +1578,13 @@
*/
int MSVCRT_fputc(int c, MSVCRT_FILE* file)
{
- return _write(file->_file, &c, 1) == 1? c : MSVCRT_EOF;
+ if(file->_cnt>0) {
+ *file->_ptr++=c;
+ file->_cnt--;
+ return c;
+ } else {
+ return _flsbuf(c, file);
+ }
}
/*********************************************************************
@@ -1471,7 +1592,24 @@
*/
int _flsbuf(int c, MSVCRT_FILE* file)
{
- return MSVCRT_fputc(c,file);
+ /* Flush output buffer */
+ if(file->_bufsiz == 0 && !(file->_flag & MSVCRT__IONBF)) {
+ msvcrt_alloc_buffer(file);
+ }
+ if(!(file->_flag & MSVCRT__IOWRT)) {
+ if(file->_flag & MSVCRT__IORW) {
+ file->_flag |= MSVCRT__IOWRT;
+ } else {
+ return MSVCRT_EOF;
+ }
+ }
+ if(file->_bufsiz) {
+ int res=msvcrt_flush_buffer(file);
+ return res?res : MSVCRT_fputc(c, file);
+ } else {
+ unsigned char cc=c;
+ return _write(file->_file, &cc, 1) == 1? c : MSVCRT_EOF;
+ }
}
/*********************************************************************
@@ -1486,10 +1624,28 @@
* fread (MSVCRT.@)
*/
MSVCRT_size_t MSVCRT_fread(void *ptr, MSVCRT_size_t size, MSVCRT_size_t nmemb, MSVCRT_FILE* file)
-{
- int read = _read(file->_file,ptr, size * nmemb);
- if (read <= 0)
- return 0;
+{ MSVCRT_size_t rcnt=size * nmemb;
+ MSVCRT_size_t read=0;
+ int pread=0;
+ /* first buffered data */
+ if(file->_cnt>0) {
+ int pcnt= (rcnt>file->_cnt)? file->_cnt:rcnt;
+ memcpy(ptr, file->_ptr, pcnt);
+ file->_cnt -= pcnt;
+ file->_ptr += pcnt;
+ read += pcnt ;
+ rcnt -= pcnt ;
+ ptr += pcnt;
+ } else if(!(file->_flag & MSVCRT__IOREAD )) {
+ if(file->_flag & MSVCRT__IORW) {
+ file->_flag |= MSVCRT__IOREAD;
+ } else
+ return 0;
+ }
+ if(rcnt) pread = _read(file->_file,ptr, rcnt);
+ if (pread <= 0)
+ pread = 0;
+ read+=pread;
return read / size;
}
@@ -1508,9 +1664,14 @@
if (fd > 2)
{
+#if 0
FIXME(":reopen on user file not implemented!\n");
MSVCRT__set_errno(ERROR_CALL_NOT_IMPLEMENTED);
return NULL;
+#endif
+ if(MSVCRT_fclose(file))
+ return NULL;
+ return MSVCRT_fopen(path, mode);
}
/* first, create the new file */
@@ -1675,6 +1836,20 @@
*/
int MSVCRT_fseek(MSVCRT_FILE* file, long offset, int whence)
{
+ /* Flush output if needed */
+ if(file->_flag & MSVCRT__IOWRT)
+ msvcrt_flush_buffer(file);
+
+ if(whence == SEEK_CUR && file->_flag & MSVCRT__IOREAD ) {
+ offset -= file->_cnt;
+ }
+ /* Discard buffered input */
+ file->_cnt = 0;
+ file->_ptr = file->_base;
+ /* Reset direction of i/o */
+ if(file->_flag & MSVCRT__IORW) {
+ file->_flag &= ~(MSVCRT__IOREAD|MSVCRT__IOWRT);
+ }
return _lseek(file->_file,offset,whence);
}
@@ -1683,7 +1858,18 @@
*/
LONG MSVCRT_ftell(MSVCRT_FILE* file)
{
- return _tell(file->_file);
+ int off=0;
+ long pos;
+ if(file->_bufsiz) {
+ if( file->_flag & MSVCRT__IOWRT ) {
+ off = file->_ptr - file->_base;
+ } else {
+ off = -file->_cnt;
+ }
+ }
+ pos = _tell(file->_file);
+ if(pos == -1) return pos;
+ return off + pos;
}
/*********************************************************************
@@ -1691,9 +1877,31 @@
*/
MSVCRT_size_t MSVCRT_fwrite(const void *ptr, MSVCRT_size_t size, MSVCRT_size_t nmemb, MSVCRT_FILE* file)
{
- int written = _write(file->_file, ptr, size * nmemb);
- if (written <= 0)
- return 0;
+ MSVCRT_size_t wrcnt=size * nmemb;
+ int written = 0;
+ if(file->_cnt) {
+ int pcnt=(file->_cnt>wrcnt)? file->_cnt: wrcnt;
+ memcpy(file->_ptr, ptr, pcnt);
+ file->_cnt -= pcnt;
+ file->_ptr += pcnt;
+ written = pcnt;
+ wrcnt -= pcnt;
+ ptr += pcnt;
+ } else if(!(file->_flag & MSVCRT__IOWRT)) {
+ if(file->_flag & MSVCRT__IORW) {
+ file->_flag |= MSVCRT__IOWRT;
+ } else
+ return 0;
+ }
+ if(wrcnt) {
+ /* Flush buffer */
+ int res=msvcrt_flush_buffer(file);
+ if(!res) {
+ int pwritten = _write(file->_file, ptr, wrcnt);
+ if (pwritten <= 0) pwritten=0;
+ written += pwritten;
+ }
+ }
return written / size;
}
@@ -1860,8 +2068,22 @@
*/
int MSVCRT_setvbuf(MSVCRT_FILE* file, char *buf, int mode, MSVCRT_size_t size)
{
- FIXME("(%p,%p,%d,%d)stub\n",file, buf, mode, size);
- return -1;
+ /* TODO: Check if file busy */
+ if(file->_bufsiz) {
+ MSVCRT_free(file->_base);
+ 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;
+ }
+ return 0;
}
/*********************************************************************
@@ -1869,7 +2091,7 @@
*/
void MSVCRT_setbuf(MSVCRT_FILE* file, char *buf)
{
- MSVCRT_setvbuf(file, buf, buf ? MSVCRT__IOFBF : MSVCRT__IONBF, BUFSIZ);
+ MSVCRT_setvbuf(file, buf, buf ? MSVCRT__IOFBF : MSVCRT__IONBF, MSVCRT_BUFSIZ);
}
/*********************************************************************
@@ -1932,6 +2154,9 @@
/*********************************************************************
* vfwprintf (MSVCRT.@)
+ * FIXME:
+ * Is final char included in written (then resize is too big) or not
+ * (then we must test for equality too)?
*/
int MSVCRT_vfwprintf(MSVCRT_FILE* file, const WCHAR *format, va_list valist)
{
@@ -1944,7 +2169,7 @@
resize = (written == -1 ? resize * 2 : written + sizeof(WCHAR));
if (mem != buf)
MSVCRT_free (mem);
- if (!(mem = (WCHAR *)MSVCRT_malloc(resize)))
+ if (!(mem = (WCHAR *)MSVCRT_malloc(resize*sizeof(*mem))))
return MSVCRT_EOF;
}
retval = MSVCRT_fwrite(mem, 1, written * sizeof (WCHAR), file);
@@ -2006,6 +2231,39 @@
res = MSVCRT_vfprintf(MSVCRT_stdout, format, valist);
va_end(valist);
return res;
+}
+
+/*********************************************************************
+ * ungetc (MSVCRT.@)
+ */
+int MSVCRT_ungetc(int c, MSVCRT_FILE * file)
+{
+ if(file->_bufsiz == 0 && !(file->_flag & MSVCRT__IONBF)) {
+ msvcrt_alloc_buffer(file);
+ file->_ptr++;
+ }
+ if(file->_ptr>file->_base) {
+ file->_ptr--;
+ *file->_ptr=c;
+ file->_cnt++;
+ return c;
+ }
+ return MSVCRT_EOF;
+}
+
+/*********************************************************************
+ * ungetwc (MSVCRT.@)
+ */
+MSVCRT_wint_t MSVCRT_ungetwc(MSVCRT_wint_t wc, MSVCRT_FILE * file)
+{
+ WCHAR mwc = wc;
+ char * pp = &mwc;
+ int i;
+ for(i=sizeof(WCHAR)-1;i>=0;i--) {
+ if(pp[i] != MSVCRT_ungetc(pp[i],file))
+ return MSVCRT_WEOF;
+ }
+ return mwc;
}
/*********************************************************************
diff -ru wine-20011226.orig/dlls/msvcrt/msvcrt.spec wine-20011226/dlls/msvcrt/msvcrt.spec
--- wine-20011226.orig/dlls/msvcrt/msvcrt.spec Fri Dec 21 21:27:39 2001
+++ wine-20011226/dlls/msvcrt/msvcrt.spec Mon Jan 7 14:18:55 2002
@@ -605,7 +605,7 @@
@ cdecl fgetpos(ptr ptr) MSVCRT_fgetpos
@ cdecl fgets(str long ptr) MSVCRT_fgets
@ cdecl fgetwc(ptr) MSVCRT_fgetwc
-@ stub fgetws #(wstr long ptr)
+@ cdecl fgetws(wstr long ptr) MSVCRT_fgetws
@ forward -noimport floor ntdll.floor
@ cdecl fmod(double double) fmod
@ cdecl fopen(str str) MSVCRT_fopen
@@ -736,8 +736,8 @@
@ cdecl toupper(long) toupper
@ forward -noimport towlower ntdll.towlower
@ forward -noimport towupper ntdll.towupper
-@ stub ungetc #(long ptr)
-@ stub ungetwc #(long ptr)
+@ cdecl ungetc(long ptr) MSVCRT_ungetc
+@ cdecl ungetwc(long ptr) MSVCRT_ungetwc
@ cdecl vfprintf(ptr str long) MSVCRT_vfprintf
@ cdecl vfwprintf(ptr wstr long) MSVCRT_vfwprintf
@ cdecl vprintf(str long) MSVCRT_vprintf
diff -ru wine-20011226.orig/include/msvcrt/stdio.h wine-20011226/include/msvcrt/stdio.h
--- wine-20011226.orig/include/msvcrt/stdio.h Mon Oct 22 20:59:23 2001
+++ wine-20011226/include/msvcrt/stdio.h Mon Jan 7 14:19:21 2002
@@ -72,6 +72,8 @@
#define MSVCRT_EOF (-1)
+#define MSVCRT_BUFSIZ 512
+
#endif /* USE_MSVCRT_PREFIX */
typedef struct MSVCRT(_iobuf)
-------------- next part --------------
#include <stdio.h>
#include <string.h>
#define MY_BSIZE 10000
int main(void)
{
FILE * file=fopen("ble.txt", "w+b");
unsigned char buff[MY_BSIZE], ibuff[MY_BSIZE];
long i, cnt;
int c;
printf("Testing binary input-output\n");
/* fill buffer */
for(i=0;i<MY_BSIZE;i++) {
buff[i] = i&0xff;
}
/* Write one block, read char by char */
printf("Test 1\n");
cnt=fwrite(buff,MY_BSIZE,1,file);
if(cnt!=1) printf("Short write, disk full ??\n");
fseek(file, 0L, SEEK_SET);
/* read char by char */
for(i=0;i<MY_BSIZE;i++) {
int c=getc(file);
if(c<0 || c>255) {
printf("Char value out of range%s\n",
(c==EOF)?", maybe unexpected EOF":"");
break;
}
ibuff[i]=c;
}
if(memcmp(buff, ibuff, MY_BSIZE))
printf("Read different values then written\n");
/* Read all file at once as one record */
printf("Test 2\n");
fseek(file, 0L, SEEK_SET);
cnt=fread(ibuff, MY_BSIZE, 1, file);
if(cnt!=1) printf("Short read\n");
if(memcmp(buff, ibuff, MY_BSIZE))
printf("Read different values then written\n");
/* Read all file at once as one byte records */
printf("Test 3\n");
fseek(file, 0L, SEEK_SET);
cnt=fread(ibuff, 1, MY_BSIZE, file);
if(cnt!=MY_BSIZE) printf("Short read\n");
if(memcmp(buff, ibuff, MY_BSIZE))
printf("Read different values then written\n");
/* fread - small blocks proportional to buffer */
printf("Test 4\n");
fseek(file, 0L, SEEK_SET);
for(i=0;i<MY_BSIZE;i+=16) {
int pcnt=(MY_BSIZE-i)<16?(MY_BSIZE-i):16;
cnt=fread(ibuff+i, pcnt, 1, file);
if(cnt!=1) {
printf("Short read\n");
break;
}
}
if(memcmp(buff, ibuff, MY_BSIZE))
printf("Read different values then written\n");
/* Mixing getc and fread */
printf("Test 5\n");
fseek(file, 0L, SEEK_SET);
for(i=0;i<MY_BSIZE;i+=160) {
int pcnt=(MY_BSIZE-i)<160?(MY_BSIZE-i):160;
int pcnt1=pcnt<80?pcnt:80;
int j;
cnt=fread(ibuff+i, pcnt1, 1, file);
if(cnt!=1) {
printf("Short read\n");
break;
}
for(j=pcnt1;j<pcnt;j++) {
int c=getc(file);
if(c==EOF) {
printf("Unexpected EOF\n");
goto fail1;
}
ibuff[i+j]=c;
}
}
if(memcmp(buff, ibuff, MY_BSIZE))
printf("Read different values then written\n");
fail1:
/* Reading backwards */
printf("Test 6\n");
i=MY_BSIZE;
do {
i-=100;
cnt=i>0?100:100+i;
fseek(file, i>0? i:0, SEEK_SET);
cnt=fread(ibuff+i, cnt, 1, file);
if(cnt!=1) {
printf("Short read\n");
break;
}
} while (i>0);
if(memcmp(buff, ibuff, MY_BSIZE))
printf("Read different values then written\n");
/* Reading backwards, mixing getc and fread */
printf("Test 7\n");
i=MY_BSIZE;
c=0;
do {
i-=100;
cnt=i>0?100:100+i;
fseek(file, i>0? i:0, SEEK_SET);
c=1-c;
if(c) {
cnt=fread(ibuff+i, cnt, 1, file);
if(cnt!=1) {
printf("Short read\n");
break;
}
} else {
int j;
for(j=0;j<100;j++) {
int cc=getc(file);
if(cc==EOF) {
printf("Unexpected EOF\n");
goto fail2;
}
ibuff[i+j]=cc;
}
}
} while (i>0);
if(memcmp(buff, ibuff, MY_BSIZE))
printf("Read different values then written\n");
fail2:
/* Using fgetpos and fsetpos */
printf("Test 8\n"); {
fpos_t pos;
long off;
fseek(file, 0L, SEEK_SET);
for(i=0;i<200;i++) {
int cc = getc(file);
if(cc==EOF) {
printf("Unexpected EOF\n");
goto fail3;
}
ibuff[i]=cc;
}
fgetpos(file, &pos);
/* off = ftell(file); */
fseek(file, 512, SEEK_SET);
cnt=fread(ibuff+512,MY_BSIZE-512,1,file);
if(cnt!=1) {
printf("Short read\n");
goto fail3;
}
fsetpos(file, &pos);
/* fseek(file, off, SEEK_SET); */
cnt=fread(ibuff+200,312,1,file);
if(cnt!=1) {
printf("Short read\n");
goto fail3;
}
}
if(memcmp(buff, ibuff, MY_BSIZE))
printf("Read different values then written\n");
fail3:
/* Writing backwards, mixing fwrite and fputc */
printf("Test 9\n");
i=MY_BSIZE;
c=0;
do {
i-=100;
cnt=i>0?100:100+i;
fseek(file, i>0? i:0, SEEK_SET);
c=1-c;
if(c) {
cnt=fwrite(buff+i, cnt, 1, file);
if(cnt!=1) {
printf("Short write\n");
break;
}
} else {
int j;
for(j=0;j<100;j++) {
putc(buff[i+j], file);
}
}
} while (i>0);
fseek(file, 0L, SEEK_SET);
cnt=fread(ibuff, MY_BSIZE, 1, file);
if(cnt!=1) {
printf("Short read\n");
}
if(memcmp(buff, ibuff, MY_BSIZE))
printf("Read different values then written\n");
/* Test of EOF conditions (feof, getc) */
printf("Test 10\n");
fseek(file, 0L, SEEK_SET);
if(feof(file)) {
printf("Unexpected EOF (1)\n");
}
fread(ibuff,MY_BSIZE,1,file);
if(feof(file)) {
printf("Unexpected EOF (2)\n");
}
getc(file);
if(!feof(file)) {
printf("Expected EOF, feof disagrees\n");
}
fseek(file, 0L, SEEK_SET);
if(feof(file)) {
printf("Unexpected EOF (3)\n");
}
for(i=0;i<MY_BSIZE+2;i++) {
if(getc(file)==EOF) break;
}
if(i!=MY_BSIZE) {
if(i<MY_BSIZE) {
printf("Unexpected EOF\n");
} else {
printf("Expected EOF, getc have not deliverd\n");
}
}
if(!feof(file)) {
printf("Expected EOF, feof disagrees\n");
}
clearerr(file);
if(feof(file)) {
printf("Unexpected EOF (4)\n");
}
return(0);
}
More information about the wine-devel
mailing list