summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs/src/imfs/imfs_linfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libfs/src/imfs/imfs_linfile.c')
-rw-r--r--cpukit/libfs/src/imfs/imfs_linfile.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/cpukit/libfs/src/imfs/imfs_linfile.c b/cpukit/libfs/src/imfs/imfs_linfile.c
new file mode 100644
index 0000000000..8a1486600b
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_linfile.c
@@ -0,0 +1,97 @@
+/**
+ * @file
+ *
+ * @ingroup IMFS
+ */
+
+/*
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "imfs.h"
+
+static ssize_t IMFS_linfile_read(
+ rtems_libio_t *iop,
+ void *buffer,
+ size_t count
+)
+{
+ IMFS_file_t *file = IMFS_iop_to_file( iop );
+ off_t start = iop->offset;
+ size_t size = file->File.size;
+ const unsigned char *data = file->Linearfile.direct;
+
+ if (count > size - start)
+ count = size - start;
+
+ IMFS_update_atime( &file->Node );
+ iop->offset = start + count;
+ memcpy(buffer, &data[start], count);
+
+ return (ssize_t) count;
+}
+
+static int IMFS_linfile_open(
+ rtems_libio_t *iop,
+ const char *pathname,
+ int oflag,
+ mode_t mode
+)
+{
+ IMFS_file_t *file;
+
+ file = iop->pathinfo.node_access;
+
+ /*
+ * Perform 'copy on write' for linear files
+ */
+ if ((iop->flags & LIBIO_FLAGS_WRITE) != 0) {
+ uint32_t count = file->File.size;
+ const unsigned char *buffer = file->Linearfile.direct;
+
+ file->Node.control = &IMFS_mknod_control_memfile.node_control;
+ file->File.size = 0;
+ file->Memfile.indirect = 0;
+ file->Memfile.doubly_indirect = 0;
+ file->Memfile.triply_indirect = 0;
+ if ((count != 0)
+ && (IMFS_memfile_write(&file->Memfile, 0, buffer, count) == -1))
+ return -1;
+ }
+
+ return 0;
+}
+
+static const rtems_filesystem_file_handlers_r IMFS_linfile_handlers = {
+ .open_h = IMFS_linfile_open,
+ .close_h = rtems_filesystem_default_close,
+ .read_h = IMFS_linfile_read,
+ .write_h = rtems_filesystem_default_write,
+ .ioctl_h = rtems_filesystem_default_ioctl,
+ .lseek_h = rtems_filesystem_default_lseek_file,
+ .fstat_h = IMFS_stat_file,
+ .ftruncate_h = rtems_filesystem_default_ftruncate,
+ .fsync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
+ .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
+ .fcntl_h = rtems_filesystem_default_fcntl,
+ .kqfilter_h = rtems_filesystem_default_kqfilter,
+ .poll_h = rtems_filesystem_default_poll,
+ .readv_h = rtems_filesystem_default_readv,
+ .writev_h = rtems_filesystem_default_writev
+};
+
+const IMFS_node_control IMFS_node_control_linfile = {
+ .handlers = &IMFS_linfile_handlers,
+ .node_initialize = IMFS_node_initialize_default,
+ .node_remove = IMFS_node_remove_default,
+ .node_destroy = IMFS_node_destroy_default
+};