summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2012-05-07 16:15:57 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2012-05-11 13:58:43 +0200
commitd61b0a5abfb00abf91ef281a89cb3984b5eef737 (patch)
tree2b22fcb26252f721a3e7c3b1a75e8e63dd743a68
parent30d412469c930fe4150ad2b9a321eea2747ec6f4 (diff)
downloadrtems-d61b0a5abfb00abf91ef281a89cb3984b5eef737.tar.bz2
Filesystem: PR1871: Fix O_APPEND
-rw-r--r--cpukit/libfs/src/dosfs/msdos.h16
-rw-r--r--cpukit/libfs/src/dosfs/msdos_dir.c64
-rw-r--r--cpukit/libfs/src/dosfs/msdos_file.c46
-rw-r--r--cpukit/libfs/src/dosfs/msdos_handlers_dir.c4
-rw-r--r--cpukit/libfs/src/dosfs/msdos_handlers_file.c2
-rw-r--r--cpukit/libfs/src/imfs/memfile.c7
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-file.c2
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c35
-rw-r--r--testsuites/fstests/fsrdwr/init.c10
9 files changed, 42 insertions, 144 deletions
diff --git a/cpukit/libfs/src/dosfs/msdos.h b/cpukit/libfs/src/dosfs/msdos.h
index a7aff1d96d..0696b8f1fb 100644
--- a/cpukit/libfs/src/dosfs/msdos.h
+++ b/cpukit/libfs/src/dosfs/msdos.h
@@ -265,13 +265,6 @@ int msdos_initialize_support(
const rtems_filesystem_file_handlers_r *directory_handlers
);
-int msdos_file_open(
- rtems_libio_t *iop, /* IN */
- const char *pathname, /* IN */
- int oflag, /* IN */
- mode_t mode /* IN */
-);
-
int msdos_file_close(rtems_libio_t *iop /* IN */);
ssize_t msdos_file_read(
@@ -301,15 +294,6 @@ int msdos_file_sync(rtems_libio_t *iop);
int msdos_file_datasync(rtems_libio_t *iop);
-int msdos_dir_open(
- rtems_libio_t *iop, /* IN */
- const char *pathname, /* IN */
- int oflag, /* IN */
- mode_t mode /* IN */
-);
-
-int msdos_dir_close(rtems_libio_t *iop /* IN */);
-
ssize_t msdos_dir_read(
rtems_libio_t *iop, /* IN */
void *buffer, /* IN */
diff --git a/cpukit/libfs/src/dosfs/msdos_dir.c b/cpukit/libfs/src/dosfs/msdos_dir.c
index be6b5a91ff..38ea6675f7 100644
--- a/cpukit/libfs/src/dosfs/msdos_dir.c
+++ b/cpukit/libfs/src/dosfs/msdos_dir.c
@@ -30,70 +30,6 @@
#include "msdos.h"
-/* msdos_dir_open --
- * Open fat-file which correspondes to the directory being opened and
- * set offset field of file control block to zero.
- */
-int
-msdos_dir_open(rtems_libio_t *iop, const char *pathname, int oflag,
- mode_t mode)
-{
- int rc = RC_OK;
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
- fat_file_fd_t *fat_fd = iop->pathinfo.node_access;
-
- sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
- MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
- if (sc != RTEMS_SUCCESSFUL)
- rtems_set_errno_and_return_minus_one( EIO );
-
- rc = fat_file_reopen(fat_fd);
- if (rc != RC_OK)
- {
- rtems_semaphore_release(fs_info->vol_sema);
- return rc;
- }
-
- iop->offset = 0;
- rtems_semaphore_release(fs_info->vol_sema);
- return RC_OK;
-}
-
-/* msdos_dir_close --
- * Close fat-file which correspondes to the directory being closed
- *
- * PARAMETERS:
- * iop - file control block
- *
- * RETURNS:
- * RC_OK, if directory closed successfully, or -1 if error occured (errno
- * set apropriately.
- */
-int
-msdos_dir_close(rtems_libio_t *iop)
-{
- int rc = RC_OK;
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
- fat_file_fd_t *fat_fd = iop->pathinfo.node_access;
-
- sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
- MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
- if (sc != RTEMS_SUCCESSFUL)
- rtems_set_errno_and_return_minus_one( EIO );
-
- rc = fat_file_close(iop->pathinfo.mt_entry, fat_fd);
- if (rc != RC_OK)
- {
- rtems_semaphore_release(fs_info->vol_sema);
- return rc;
- }
-
- rtems_semaphore_release(fs_info->vol_sema);
- return RC_OK;
-}
-
/* msdos_format_dirent_with_dot --
* This routine convert a (short) MSDOS filename as present on disk
* (fixed 8+3 characters, filled with blanks, without separator dot)
diff --git a/cpukit/libfs/src/dosfs/msdos_file.c b/cpukit/libfs/src/dosfs/msdos_file.c
index c2db196c77..6eb9b7953a 100644
--- a/cpukit/libfs/src/dosfs/msdos_file.c
+++ b/cpukit/libfs/src/dosfs/msdos_file.c
@@ -27,47 +27,6 @@
#include "msdos.h"
-/* msdos_file_open --
- * Open fat-file which correspondes to the file
- *
- * PARAMETERS:
- * iop - file control block
- * pathname - name
- * flag - flags
- * mode - mode
- *
- * RETURNS:
- * RC_OK, if file opened successfully, or -1 if error occured
- * and errno set appropriately
- */
-int
-msdos_file_open(rtems_libio_t *iop, const char *pathname, int oflag,
- mode_t mode)
-{
- int rc = RC_OK;
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
- fat_file_fd_t *fat_fd = iop->pathinfo.node_access;
-
- sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
- MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
- if (sc != RTEMS_SUCCESSFUL)
- rtems_set_errno_and_return_minus_one(EIO);
-
- rc = fat_file_reopen(fat_fd);
- if (rc != RC_OK)
- {
- rtems_semaphore_release(fs_info->vol_sema);
- return rc;
- }
-
- if (iop->flags & LIBIO_FLAGS_APPEND)
- iop->offset = fat_fd->fat_file_size;
-
- rtems_semaphore_release(fs_info->vol_sema);
- return RC_OK;
-}
-
/* msdos_file_close --
* Close fat-file which correspondes to the file. If fat-file descriptor
* which correspondes to the file is not marked "removed", synchronize
@@ -121,8 +80,6 @@ msdos_file_close(rtems_libio_t *iop)
}
}
- rc = fat_file_close(iop->pathinfo.mt_entry, fat_fd);
-
rtems_semaphore_release(fs_info->vol_sema);
return rc;
}
@@ -186,6 +143,9 @@ msdos_file_write(rtems_libio_t *iop,const void *buffer, size_t count)
if (sc != RTEMS_SUCCESSFUL)
rtems_set_errno_and_return_minus_one(EIO);
+ if ((iop->flags & LIBIO_FLAGS_APPEND) != 0)
+ iop->offset = fat_fd->fat_file_size;
+
ret = fat_file_write(iop->pathinfo.mt_entry, fat_fd, iop->offset, count,
buffer);
if (ret < 0)
diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_dir.c b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c
index eeaa77d15e..8c7dcdc0a5 100644
--- a/cpukit/libfs/src/dosfs/msdos_handlers_dir.c
+++ b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c
@@ -19,8 +19,8 @@
#include "msdos.h"
const rtems_filesystem_file_handlers_r msdos_dir_handlers = {
- msdos_dir_open,
- msdos_dir_close,
+ rtems_filesystem_default_open,
+ rtems_filesystem_default_close,
msdos_dir_read,
rtems_filesystem_default_write,
rtems_filesystem_default_ioctl,
diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_file.c b/cpukit/libfs/src/dosfs/msdos_handlers_file.c
index e68a09f1d3..12cdaa048e 100644
--- a/cpukit/libfs/src/dosfs/msdos_handlers_file.c
+++ b/cpukit/libfs/src/dosfs/msdos_handlers_file.c
@@ -19,7 +19,7 @@
#include "msdos.h"
const rtems_filesystem_file_handlers_r msdos_file_handlers = {
- msdos_file_open,
+ rtems_filesystem_default_open,
msdos_file_close,
msdos_file_read,
msdos_file_write,
diff --git a/cpukit/libfs/src/imfs/memfile.c b/cpukit/libfs/src/imfs/memfile.c
index 64679df037..d836172884 100644
--- a/cpukit/libfs/src/imfs/memfile.c
+++ b/cpukit/libfs/src/imfs/memfile.c
@@ -92,7 +92,7 @@ int memfile_open(
/*
* Perform 'copy on write' for linear files
*/
- if ((iop->flags & (LIBIO_FLAGS_WRITE | LIBIO_FLAGS_APPEND))
+ if ((iop->flags & LIBIO_FLAGS_WRITE)
&& (IMFS_type( the_jnode ) == IMFS_LINEAR_FILE)) {
uint32_t count = the_jnode->info.linearfile.size;
const unsigned char *buffer = the_jnode->info.linearfile.direct;
@@ -106,8 +106,6 @@ int memfile_open(
&& (IMFS_memfile_write(the_jnode, 0, buffer, count) == -1))
return -1;
}
- if (iop->flags & LIBIO_FLAGS_APPEND)
- iop->offset = the_jnode->info.file.size;
return 0;
}
@@ -146,6 +144,9 @@ ssize_t memfile_write(
the_jnode = iop->pathinfo.node_access;
+ if ((iop->flags & LIBIO_FLAGS_APPEND) != 0)
+ iop->offset = the_jnode->info.file.size;
+
status = IMFS_memfile_write( the_jnode, iop->offset, buffer, count );
return status;
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-file.c b/cpukit/libfs/src/rfs/rtems-rfs-file.c
index abd123da1b..ab195fac6f 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-file.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-file.c
@@ -422,7 +422,7 @@ rtems_rfs_file_seek (rtems_rfs_file_handle* handle,
* This means the file needs to set the file size to the pos only when a
* write occurs.
*/
- if (pos < rtems_rfs_file_shared_get_size (rtems_rfs_file_fs (handle),
+ if (pos <= rtems_rfs_file_shared_get_size (rtems_rfs_file_fs (handle),
handle->shared))
{
rtems_rfs_file_set_bpos (handle, pos);
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c
index b2ff45df8b..1b8b0d4441 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c
@@ -185,6 +185,7 @@ rtems_rfs_rtems_file_write (rtems_libio_t* iop,
{
rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
rtems_rfs_pos pos;
+ rtems_rfs_pos file_size;
const uint8_t* data = buffer;
ssize_t write = 0;
int rc;
@@ -195,26 +196,34 @@ rtems_rfs_rtems_file_write (rtems_libio_t* iop,
rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
pos = iop->offset;
-
- /*
- * If the iop position is past the physical end of the file we need to set
- * the file size to the new length before writing. If the position equals the
- * size of file we are still past the end of the file as positions number
- * from 0. For a specific position we need a file that has a length of one
- * more.
- */
-
- if (pos >= rtems_rfs_file_size (file))
+ file_size = rtems_rfs_file_size (file);
+ if (pos > file_size)
{
- rc = rtems_rfs_file_set_size (file, pos + 1);
+ /*
+ * If the iop position is past the physical end of the file we need to set
+ * the file size to the new length before writing. The
+ * rtems_rfs_file_io_end() will grow the file subsequently.
+ */
+ rc = rtems_rfs_file_set_size (file, pos);
if (rc)
{
rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
return rtems_rfs_rtems_error ("file-write: write extend", rc);
}
- }
- rtems_rfs_file_set_bpos (file, pos);
+ rtems_rfs_file_set_bpos (file, pos);
+ }
+ else if (pos < file_size && (iop->flags & LIBIO_FLAGS_APPEND) != 0)
+ {
+ pos = file_size;
+ rc = rtems_rfs_file_seek (file, pos, &pos);
+ if (rc)
+ {
+ rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
+ return rtems_rfs_rtems_error ("file-write: write append seek", rc);
+ }
+ iop->offset = pos;
+ }
while (count)
{
diff --git a/testsuites/fstests/fsrdwr/init.c b/testsuites/fstests/fsrdwr/init.c
index 8b40f07581..bfaa8abf7e 100644
--- a/testsuites/fstests/fsrdwr/init.c
+++ b/testsuites/fstests/fsrdwr/init.c
@@ -112,6 +112,12 @@ read_write_test (void)
rtems_test_assert (n == len);
pos = lseek (fd, 0, SEEK_CUR);
rtems_test_assert (pos == 2 * len);
+ pos = lseek (fd, 0, SEEK_SET);
+ rtems_test_assert (pos == 0);
+ n = write (fd, databuf, len);
+ rtems_test_assert (n == len);
+ pos = lseek (fd, 0, SEEK_CUR);
+ rtems_test_assert (pos == 3 * len);
status = close (fd);
rtems_test_assert (status == 0);
@@ -123,7 +129,9 @@ read_write_test (void)
n = read (fd, readbuf, len);
rtems_test_assert (n == len);
rtems_test_assert (!strncmp (databuf, readbuf, len));
-
+ n = read (fd, readbuf, len);
+ rtems_test_assert (n == len);
+ rtems_test_assert (!strncmp (databuf, readbuf, len));
n = read (fd, readbuf, len);
rtems_test_assert (n == len);
rtems_test_assert (!strncmp (databuf, readbuf, len));