summaryrefslogtreecommitdiff
path: root/nuttx/lib/lib_libfwrite.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-02-05 18:13:13 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-02-05 18:13:13 +0000
commitd1f1e007f149be8a8c3084d144599a7456d15aba (patch)
treedc4794aec1816bddcdf86ad50da6c7ebe86b4d51 /nuttx/lib/lib_libfwrite.c
parente05c8208701c52f71abfda389c5dbbea8cf380a7 (diff)
downloadpx4-nuttx-d1f1e007f149be8a8c3084d144599a7456d15aba.tar.gz
px4-nuttx-d1f1e007f149be8a8c3084d144599a7456d15aba.tar.bz2
px4-nuttx-d1f1e007f149be8a8c3084d144599a7456d15aba.zip
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
Diffstat (limited to 'nuttx/lib/lib_libfwrite.c')
-rw-r--r--nuttx/lib/lib_libfwrite.c106
1 files changed, 60 insertions, 46 deletions
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
{