forked from Imagelibrary/rtems
Filesystem: PR1871: Fix O_APPEND
This commit is contained in:
@@ -265,13 +265,6 @@ int msdos_initialize_support(
|
|||||||
const rtems_filesystem_file_handlers_r *directory_handlers
|
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 */);
|
int msdos_file_close(rtems_libio_t *iop /* IN */);
|
||||||
|
|
||||||
ssize_t msdos_file_read(
|
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_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(
|
ssize_t msdos_dir_read(
|
||||||
rtems_libio_t *iop, /* IN */
|
rtems_libio_t *iop, /* IN */
|
||||||
void *buffer, /* IN */
|
void *buffer, /* IN */
|
||||||
|
|||||||
@@ -30,70 +30,6 @@
|
|||||||
|
|
||||||
#include "msdos.h"
|
#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 --
|
/* msdos_format_dirent_with_dot --
|
||||||
* This routine convert a (short) MSDOS filename as present on disk
|
* This routine convert a (short) MSDOS filename as present on disk
|
||||||
* (fixed 8+3 characters, filled with blanks, without separator dot)
|
* (fixed 8+3 characters, filled with blanks, without separator dot)
|
||||||
|
|||||||
@@ -27,47 +27,6 @@
|
|||||||
|
|
||||||
#include "msdos.h"
|
#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 --
|
/* msdos_file_close --
|
||||||
* Close fat-file which correspondes to the file. If fat-file descriptor
|
* Close fat-file which correspondes to the file. If fat-file descriptor
|
||||||
* which correspondes to the file is not marked "removed", synchronize
|
* 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);
|
rtems_semaphore_release(fs_info->vol_sema);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -186,6 +143,9 @@ msdos_file_write(rtems_libio_t *iop,const void *buffer, size_t count)
|
|||||||
if (sc != RTEMS_SUCCESSFUL)
|
if (sc != RTEMS_SUCCESSFUL)
|
||||||
rtems_set_errno_and_return_minus_one(EIO);
|
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,
|
ret = fat_file_write(iop->pathinfo.mt_entry, fat_fd, iop->offset, count,
|
||||||
buffer);
|
buffer);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
|||||||
@@ -19,8 +19,8 @@
|
|||||||
#include "msdos.h"
|
#include "msdos.h"
|
||||||
|
|
||||||
const rtems_filesystem_file_handlers_r msdos_dir_handlers = {
|
const rtems_filesystem_file_handlers_r msdos_dir_handlers = {
|
||||||
msdos_dir_open,
|
rtems_filesystem_default_open,
|
||||||
msdos_dir_close,
|
rtems_filesystem_default_close,
|
||||||
msdos_dir_read,
|
msdos_dir_read,
|
||||||
rtems_filesystem_default_write,
|
rtems_filesystem_default_write,
|
||||||
rtems_filesystem_default_ioctl,
|
rtems_filesystem_default_ioctl,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include "msdos.h"
|
#include "msdos.h"
|
||||||
|
|
||||||
const rtems_filesystem_file_handlers_r msdos_file_handlers = {
|
const rtems_filesystem_file_handlers_r msdos_file_handlers = {
|
||||||
msdos_file_open,
|
rtems_filesystem_default_open,
|
||||||
msdos_file_close,
|
msdos_file_close,
|
||||||
msdos_file_read,
|
msdos_file_read,
|
||||||
msdos_file_write,
|
msdos_file_write,
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ int memfile_open(
|
|||||||
/*
|
/*
|
||||||
* Perform 'copy on write' for linear files
|
* 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)) {
|
&& (IMFS_type( the_jnode ) == IMFS_LINEAR_FILE)) {
|
||||||
uint32_t count = the_jnode->info.linearfile.size;
|
uint32_t count = the_jnode->info.linearfile.size;
|
||||||
const unsigned char *buffer = the_jnode->info.linearfile.direct;
|
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))
|
&& (IMFS_memfile_write(the_jnode, 0, buffer, count) == -1))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (iop->flags & LIBIO_FLAGS_APPEND)
|
|
||||||
iop->offset = the_jnode->info.file.size;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -146,6 +144,9 @@ ssize_t memfile_write(
|
|||||||
|
|
||||||
the_jnode = iop->pathinfo.node_access;
|
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 );
|
status = IMFS_memfile_write( the_jnode, iop->offset, buffer, count );
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|||||||
@@ -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
|
* This means the file needs to set the file size to the pos only when a
|
||||||
* write occurs.
|
* 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))
|
handle->shared))
|
||||||
{
|
{
|
||||||
rtems_rfs_file_set_bpos (handle, pos);
|
rtems_rfs_file_set_bpos (handle, pos);
|
||||||
|
|||||||
@@ -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_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
|
||||||
rtems_rfs_pos pos;
|
rtems_rfs_pos pos;
|
||||||
|
rtems_rfs_pos file_size;
|
||||||
const uint8_t* data = buffer;
|
const uint8_t* data = buffer;
|
||||||
ssize_t write = 0;
|
ssize_t write = 0;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -195,26 +196,34 @@ rtems_rfs_rtems_file_write (rtems_libio_t* iop,
|
|||||||
rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
|
rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
|
||||||
|
|
||||||
pos = iop->offset;
|
pos = iop->offset;
|
||||||
|
file_size = rtems_rfs_file_size (file);
|
||||||
|
if (pos > file_size)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* If the iop position is past the physical end of the file we need to set
|
* 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
|
* the file size to the new length before writing. The
|
||||||
* size of file we are still past the end of the file as positions number
|
* rtems_rfs_file_io_end() will grow the file subsequently.
|
||||||
* from 0. For a specific position we need a file that has a length of one
|
|
||||||
* more.
|
|
||||||
*/
|
*/
|
||||||
|
rc = rtems_rfs_file_set_size (file, pos);
|
||||||
if (pos >= rtems_rfs_file_size (file))
|
|
||||||
{
|
|
||||||
rc = rtems_rfs_file_set_size (file, pos + 1);
|
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
|
rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
|
||||||
return rtems_rfs_rtems_error ("file-write: write extend", rc);
|
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)
|
while (count)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -112,6 +112,12 @@ read_write_test (void)
|
|||||||
rtems_test_assert (n == len);
|
rtems_test_assert (n == len);
|
||||||
pos = lseek (fd, 0, SEEK_CUR);
|
pos = lseek (fd, 0, SEEK_CUR);
|
||||||
rtems_test_assert (pos == 2 * len);
|
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);
|
status = close (fd);
|
||||||
rtems_test_assert (status == 0);
|
rtems_test_assert (status == 0);
|
||||||
|
|
||||||
@@ -123,7 +129,9 @@ read_write_test (void)
|
|||||||
n = read (fd, readbuf, len);
|
n = read (fd, readbuf, len);
|
||||||
rtems_test_assert (n == len);
|
rtems_test_assert (n == len);
|
||||||
rtems_test_assert (!strncmp (databuf, readbuf, 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);
|
n = read (fd, readbuf, len);
|
||||||
rtems_test_assert (n == len);
|
rtems_test_assert (n == len);
|
||||||
rtems_test_assert (!strncmp (databuf, readbuf, len));
|
rtems_test_assert (!strncmp (databuf, readbuf, len));
|
||||||
|
|||||||
Reference in New Issue
Block a user