From d1f1e007f149be8a8c3084d144599a7456d15aba Mon Sep 17 00:00:00 2001 From: patacongo Date: Tue, 5 Feb 2008 18:13:13 +0000 Subject: Various fixes for buffered R/W I/O and seeking git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@630 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/lib/lib_libfwrite.c | 106 ++++++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 46 deletions(-) (limited to 'nuttx/lib/lib_libfwrite.c') diff --git a/nuttx/lib/lib_libfwrite.c b/nuttx/lib/lib_libfwrite.c index 361d88127..01bc3c285 100644 --- a/nuttx/lib/lib_libfwrite.c +++ b/nuttx/lib/lib_libfwrite.c @@ -83,7 +83,7 @@ ****************************************************************************/ /**************************************************************************** - * lib_fwrite + * Name: lib_fwrite ****************************************************************************/ ssize_t lib_fwrite(const void *ptr, size_t count, FILE *stream) @@ -91,73 +91,87 @@ ssize_t lib_fwrite(const void *ptr, size_t count, FILE *stream) { const unsigned char *start = ptr; const unsigned char *src = ptr; - ssize_t bytes_written; + ssize_t ret = ERROR; unsigned char *dest; /* Make sure that writing to this stream is allowed */ - if ((!stream) || ((stream->fs_oflags & O_WROK) == 0)) + if (!stream || (stream->fs_oflags & O_WROK) == 0) { *get_errno_ptr() = EBADF; - bytes_written = -1; + goto errout; } - else + + /* Get exclusive access to the stream */ + + lib_take_semaphore(stream); + + /* If the buffer is currently being used for read access, then + * discard all of the read-ahead data. We do not support concurrent + * buffered read/write access. + */ + + if (lib_rdflush(stream) < 0) { - /* Loop until all of the bytes have been buffered */ + goto errout_with_semaphore; + } - lib_take_semaphore(stream); - while (count > 0) - { - /* Determine the number of bytes left in the buffer */ + /* Loop until all of the bytes have been buffered */ - size_t gulp_size = stream->fs_bufend - stream->fs_bufpos; + while (count > 0) + { + /* Determine the number of bytes left in the buffer */ - /* Will the user data fit into the amount of buffer space - * that we have left? - */ + size_t gulp_size = stream->fs_bufend - stream->fs_bufpos; - if (gulp_size > count) - { - /* Yes, clip the gulp to the size of the user data */ + /* Will the user data fit into the amount of buffer space + * that we have left? + */ - gulp_size = count; - } + if (gulp_size > count) + { + /* Yes, clip the gulp to the size of the user data */ - /* Adjust the number of bytes remaining to be transferred - * on the next pass through the loop (might be zero). - */ + gulp_size = count; + } - count -= gulp_size; + /* Adjust the number of bytes remaining to be transferred + * on the next pass through the loop (might be zero). + */ - /* Transfer the data into the buffer */ + count -= gulp_size; - for (dest = stream->fs_bufpos; gulp_size > 0; gulp_size--) - { - *dest++ = *src++; - } - stream->fs_bufpos = dest; + /* Transfer the data into the buffer */ - /* Is the buffer full? */ + for (dest = stream->fs_bufpos; gulp_size > 0; gulp_size--) + { + *dest++ = *src++; + } + stream->fs_bufpos = dest; - if (dest >= stream->fs_bufend) - { - /* flush the buffered data to the IO stream */ + /* Is the buffer full? */ - int bytes_buffered = fflush(stream); - if (bytes_buffered < 0) - { - bytes_written = bytes_buffered; - goto err_out; - } - } - } - - bytes_written = src - start; + if (dest >= stream->fs_bufend) + { + /* Flush the buffered data to the IO stream */ - err_out: - lib_give_semaphore(stream); + int bytes_buffered = fflush_internal(stream, FALSE); + if (bytes_buffered < 0) + { + goto errout_with_semaphore; + } + } } - return bytes_written; + + /* Return the number of bytes written */ + + ret = src - start; + +errout_with_semaphore: + lib_give_semaphore(stream); + +errout: + return ret; } #else { -- cgit v1.2.3