From e6cd86e6ad28ef31d4182d6487ede0eac59893a0 Mon Sep 17 00:00:00 2001 From: mumurik2 Date: Thu, 29 Apr 2010 22:42:11 +0900 Subject: [PATCH] fwrite fix. --- mona/core/monalibc/stdio/fflush.c | 13 +++++++++++-- mona/core/monalibc/stdio/fopen.c | 17 +++++++++++------ mona/core/monalibc/stdio/fseek.c | 1 + mona/core/monalibc/stdio/fwrite.c | 29 +++++++++++++++++++---------- mona/core/scheme/lib/conf.scm.in | 1 + mona/test/monalibc/stdio/test.cpp | 23 +++++++++++++++++++++++ mona/test/monapi/ram_disk/Makefile | 2 +- 7 files changed, 67 insertions(+), 19 deletions(-) diff --git a/mona/core/monalibc/stdio/fflush.c b/mona/core/monalibc/stdio/fflush.c index 2c73de8f1..cb45d77bd 100644 --- a/mona/core/monalibc/stdio/fflush.c +++ b/mona/core/monalibc/stdio/fflush.c @@ -41,9 +41,18 @@ int fflush(FILE *stream) } else if( stream->_flags & __SFBF ) { - stream->_seek(stream, stream->_extra->offset, SEEK_SET); if( stream->_flags & __SWR ) - stream->_write(stream, stream->_bf._base, stream->_bf._size); + { + if(stream->_bf._range > 0) + { + stream->_seek(stream, stream->_bf._offset, SEEK_SET); + stream->_write(stream, stream->_bf._base, stream->_bf._range); + } + stream->_bf._offset = stream->_extra->offset; + stream->_bf._range = 0; + } + stream->_seek(stream, stream->_extra->offset, SEEK_SET); + return 0; } else if( stream->_flags & __SLBF ) { diff --git a/mona/core/monalibc/stdio/fopen.c b/mona/core/monalibc/stdio/fopen.c index 4f6b596a6..5df83d60d 100644 --- a/mona/core/monalibc/stdio/fopen.c +++ b/mona/core/monalibc/stdio/fopen.c @@ -109,12 +109,17 @@ FILE *fopen(const char *path, const char *mode) fp->_extra->filesize = (fpos_t)monapi_file_get_file_size(fp->_file); fp->_ungetcbuf = EOF; - fp->_bf._size = BUFSIZ; - fp->_flags |= __SALD|__SFBF|__SOAL; - /* - fp->_bf._size = 0; - fp->_flags |= __SNBF; - */ + // if read+write, nobuffer. + if(((fp->_flags & __SWR) || (fp->_flags & __SAP)) && (fp->_flags & __SRD)) + { + fp->_bf._size = 0; + fp->_flags |= __SNBF; + } + else + { + fp->_bf._size = BUFSIZ; + fp->_flags |= __SALD|__SFBF|__SOAL; + } return fp; } diff --git a/mona/core/monalibc/stdio/fseek.c b/mona/core/monalibc/stdio/fseek.c index aacf90770..aa84ad74d 100644 --- a/mona/core/monalibc/stdio/fseek.c +++ b/mona/core/monalibc/stdio/fseek.c @@ -38,6 +38,7 @@ int fseek(FILE *stream, long offset, int whence) { register int result; // stream->_extra->filesize = monapi_file_get_file_size(stream->_file); + fflush(stream); switch(whence) { case SEEK_SET: diff --git a/mona/core/monalibc/stdio/fwrite.c b/mona/core/monalibc/stdio/fwrite.c index cca88d86e..64a575db7 100644 --- a/mona/core/monalibc/stdio/fwrite.c +++ b/mona/core/monalibc/stdio/fwrite.c @@ -53,26 +53,35 @@ size_t __nida_nonebuf_fwrite(const void *ptr, size_t size, FILE *stream) return writesize; } +static int target_inside_buffer(int bufoff, int bufsize, int targetoff, int targetsize) +{ + return ( bufoff <= targetoff && + bufoff+bufsize >= targetoff+targetsize); +} + size_t __nida_fullybuf_fwrite(const void *ptr, size_t size, FILE *stream) { size_t writesize; int offdiff; - if( stream->_bf._offset <= stream->_extra->offset && - stream->_bf._offset+stream->_bf._range >= stream->_extra->offset+size); + struct __sbuf *bf = &stream->_bf; + struct __sFILEX *extra = stream->_extra; + if(!target_inside_buffer(bf->_offset, bf->_size, extra->offset, size)) { - offdiff = stream->_extra->offset-stream->_bf._offset; - writesize = size; - if( stream->_bf._size < size ) + fflush(stream); + if(!target_inside_buffer(bf->_offset, bf->_size, extra->offset, size)) { - writesize = stream->_bf._size; + return stream->_write(stream, (void*)ptr, size); } - memcpy(stream->_bf._base+offdiff, ptr, writesize); + /* fall through */ } + offdiff = extra->offset-bf->_offset; + memcpy(bf->_base+offdiff, ptr, size); + extra->offset += size; + if(bf->_range < offdiff+size) + bf->_range = offdiff+size; + return size; - stream->_write(stream, (void*)ptr, size); - - return writesize; } size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) diff --git a/mona/core/scheme/lib/conf.scm.in b/mona/core/scheme/lib/conf.scm.in index 29ee91892..aac7e8523 100644 --- a/mona/core/scheme/lib/conf.scm.in +++ b/mona/core/scheme/lib/conf.scm.in @@ -334,6 +334,7 @@ (call-process "/APPS/TSTDIO.APP/TSTDIO.EX5") (call-process "/APPS/TMSG.EX5") (call-process "/APPS/TSOCK.EX5") +(call-process "/APPS/TRAMDISK.EX5") ;(call-process "/APPS/HELLO.EX5") ;(start-process "/APPS/NET.EX5") diff --git a/mona/test/monalibc/stdio/test.cpp b/mona/test/monalibc/stdio/test.cpp index 9b5ff3949..332d4e859 100644 --- a/mona/test/monalibc/stdio/test.cpp +++ b/mona/test/monalibc/stdio/test.cpp @@ -10,6 +10,7 @@ int test2(); int test3(); int test4(); int test5(); +void testFWriteSmall(); int main(int argc, char* argv[]) { @@ -22,6 +23,7 @@ int main(int argc, char* argv[]) test3(); test4(); test5(); + testFWriteSmall(); TEST_RESULTS(stdio); return 0; } @@ -84,3 +86,24 @@ int test5() EXPECT_EQ(fileno(stdout), fileno(stdout)); EXPECT_EQ(fileno(stderr), fileno(stderr)); } + +static int fileSize(const char* path) +{ + uint32_t id = monapi_file_open(path, false); + int actual = monapi_file_get_file_size(id); + monapi_file_close(id); + return actual; +} + +void testFWriteSmall() +{ + const char* path; + FILE* fp = fopen("/MEM/TEST.DAT", "w"); + EXPECT_TRUE(fp != NULL); + const char buf[] = "test"; + fwrite(buf, sizeof(char), sizeof(buf), fp); + fclose(fp); + + EXPECT_EQ(sizeof(buf), fileSize("/MEM/TEST.DAT")); + monapi_file_delete("/MEM/TEST.DAT"); +} diff --git a/mona/test/monapi/ram_disk/Makefile b/mona/test/monapi/ram_disk/Makefile index 2efaaa413..e3a588a7b 100644 --- a/mona/test/monapi/ram_disk/Makefile +++ b/mona/test/monapi/ram_disk/Makefile @@ -2,7 +2,7 @@ ifndef $(MONADIR) export MONADIR=$(shell cd $(PWD)/../../../; pwd) endif -TARGET = RAMDISK +TARGET = TRAMDISK SOURCES = ram_disk.cpp INSTDIR = $(BINDIR)/APPS