[PATCH 3/3] imfs: Add IMFS_make_linfile()

Sebastian Huber sebastian.huber at embedded-brains.de
Mon Nov 18 07:10:48 UTC 2019


Update #3818.
---
 cpukit/Makefile.am                             |  1 +
 cpukit/include/rtems/imfs.h                    | 31 +++++++++++++
 cpukit/libfs/src/imfs/imfs_linfile.c           | 18 +++++++-
 cpukit/libfs/src/imfs/imfs_load_tar.c          | 29 ++++++-------
 cpukit/libfs/src/imfs/imfs_make_generic_node.c | 25 +++++++++--
 cpukit/libfs/src/imfs/imfs_make_linfile.c      | 53 +++++++++++++++++++++++
 testsuites/libtests/shell01/init.c             | 60 +++++++++++++-------------
 7 files changed, 166 insertions(+), 51 deletions(-)
 create mode 100644 cpukit/libfs/src/imfs/imfs_make_linfile.c

diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am
index 7698fe5482..71daca821a 100644
--- a/cpukit/Makefile.am
+++ b/cpukit/Makefile.am
@@ -428,6 +428,7 @@ librtemscpu_a_SOURCES += libfs/src/imfs/imfs_linfile.c
 librtemscpu_a_SOURCES += libfs/src/imfs/imfs_link.c
 librtemscpu_a_SOURCES += libfs/src/imfs/imfs_load_tar.c
 librtemscpu_a_SOURCES += libfs/src/imfs/imfs_make_generic_node.c
+librtemscpu_a_SOURCES += libfs/src/imfs/imfs_make_linfile.c
 librtemscpu_a_SOURCES += libfs/src/imfs/imfs_memfile.c
 librtemscpu_a_SOURCES += libfs/src/imfs/imfs_mknod.c
 librtemscpu_a_SOURCES += libfs/src/imfs/imfs_mount.c
diff --git a/cpukit/include/rtems/imfs.h b/cpukit/include/rtems/imfs.h
index e83209508c..27105fc257 100644
--- a/cpukit/include/rtems/imfs.h
+++ b/cpukit/include/rtems/imfs.h
@@ -317,6 +317,11 @@ typedef struct {
   void         *context;
 } IMFS_generic_t;
 
+typedef struct {
+  const void *data;
+  size_t      size;
+} IMFS_linearfile_context;
+
 static inline IMFS_directory_t *IMFS_iop_to_directory(
   const rtems_libio_t *iop
 )
@@ -592,6 +597,32 @@ static inline bool IMFS_is_imfs_instance(
   return loc->mt_entry->ops->clonenod_h == IMFS_node_clone;
 }
 
+extern int IMFS_make_node(
+  const char              *path,
+  mode_t                   mode,
+  const IMFS_node_control *node_control,
+  size_t                   node_size,
+  void                    *context
+);
+
+/**
+ * @brief Makes a linear IMFS file.
+ *
+ * @param path The path to the new linear IMFS file.
+ * @param mode The file mode permissions.  S_IFREG is set by the function.
+ * @param data The begin of linear file data area.
+ * @param size The size of the linear file data area in bytes.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred.  The @c errno indicates the error.
+ */
+extern int IMFS_make_linearfile(
+  const char *path,
+  mode_t      mode,
+  const char *data,
+  size_t      size
+);
+
 /** @} */
 
 /**
diff --git a/cpukit/libfs/src/imfs/imfs_linfile.c b/cpukit/libfs/src/imfs/imfs_linfile.c
index f53930d4b0..2044cc66fc 100644
--- a/cpukit/libfs/src/imfs/imfs_linfile.c
+++ b/cpukit/libfs/src/imfs/imfs_linfile.c
@@ -95,9 +95,25 @@ static const rtems_filesystem_file_handlers_r IMFS_linfile_handlers = {
   .writev_h = rtems_filesystem_default_writev
 };
 
+static IMFS_jnode_t *IMFS_node_initialize_linfile(
+  IMFS_jnode_t *node,
+  void         *arg
+)
+{
+  IMFS_linearfile_t *linfile;
+  IMFS_linearfile_context *ctx;
+
+  linfile = (IMFS_linearfile_t *) node;
+  ctx = arg;
+  linfile->File.size = ctx->size;
+  linfile->direct = RTEMS_DECONST( void *, ctx->data );
+
+  return node;
+}
+
 const IMFS_node_control IMFS_node_control_linfile = {
   .handlers = &IMFS_linfile_handlers,
-  .node_initialize = IMFS_node_initialize_default,
+  .node_initialize = IMFS_node_initialize_linfile,
   .node_remove = IMFS_node_remove_default,
   .node_destroy = IMFS_node_destroy_default
 };
diff --git a/cpukit/libfs/src/imfs/imfs_load_tar.c b/cpukit/libfs/src/imfs/imfs_load_tar.c
index e83553866a..6298a3f32d 100644
--- a/cpukit/libfs/src/imfs/imfs_load_tar.c
+++ b/cpukit/libfs/src/imfs/imfs_load_tar.c
@@ -135,21 +135,20 @@ int rtems_tarfs_load(
       rtems_filesystem_eval_path_continue( &ctx );
 
       if ( !rtems_filesystem_location_is_null( currentloc ) ) {
-        IMFS_linearfile_t *linfile = (IMFS_linearfile_t *)
-          IMFS_create_node(
-            currentloc,
-            &IMFS_node_control_linfile,
-            sizeof( IMFS_file_t ),
-            rtems_filesystem_eval_path_get_token( &ctx ),
-            rtems_filesystem_eval_path_get_tokenlen( &ctx ),
-            (file_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG,
-            NULL
-          );
-
-        if ( linfile != NULL ) {
-          linfile->File.size = file_size;
-          linfile->direct    = &tar_image[offset];
-        }
+        IMFS_linearfile_context linctx = {
+          .data = &tar_image[offset],
+          .size = file_size
+        };
+
+        IMFS_create_node(
+          currentloc,
+          &IMFS_node_control_linfile,
+          sizeof( IMFS_file_t ),
+          rtems_filesystem_eval_path_get_token( &ctx ),
+          rtems_filesystem_eval_path_get_tokenlen( &ctx ),
+          (file_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG,
+          &linctx
+        );
       }
 
       nblocks = (((file_size) + 511) & ~511) / 512;
diff --git a/cpukit/libfs/src/imfs/imfs_make_generic_node.c b/cpukit/libfs/src/imfs/imfs_make_generic_node.c
index ce610e5eca..27ef618d0b 100644
--- a/cpukit/libfs/src/imfs/imfs_make_generic_node.c
+++ b/cpukit/libfs/src/imfs/imfs_make_generic_node.c
@@ -40,10 +40,27 @@ IMFS_jnode_t *IMFS_node_initialize_generic(
 }
 
 int IMFS_make_generic_node(
-  const char *path,
-  mode_t mode,
+  const char              *path,
+  mode_t                   mode,
   const IMFS_node_control *node_control,
-  void *context
+  void                    *context
+)
+{
+  return IMFS_make_node(
+    path,
+    mode,
+    node_control,
+    sizeof( IMFS_generic_t ),
+    context
+  );
+}
+
+int IMFS_make_node(
+  const char              *path,
+  mode_t                   mode,
+  const IMFS_node_control *node_control,
+  size_t                   node_size,
+  void                    *context
 )
 {
   int rv = 0;
@@ -75,7 +92,7 @@ int IMFS_make_generic_node(
       IMFS_jnode_t *new_node = IMFS_create_node(
         currentloc,
         node_control,
-        sizeof( IMFS_generic_t ),
+        node_size,
         rtems_filesystem_eval_path_get_token( &ctx ),
         rtems_filesystem_eval_path_get_tokenlen( &ctx ),
         mode,
diff --git a/cpukit/libfs/src/imfs/imfs_make_linfile.c b/cpukit/libfs/src/imfs/imfs_make_linfile.c
new file mode 100644
index 0000000000..d5f1d0e21f
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_make_linfile.c
@@ -0,0 +1,53 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2019 embedded brains GmbH
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/imfs.h>
+
+int IMFS_make_linearfile(
+  const char *path,
+  mode_t      mode,
+  const char *data,
+  size_t      size
+)
+{
+  IMFS_linearfile_context ctx = {
+    .data = data,
+    .size = size
+  };
+
+  return IMFS_make_node(
+    path,
+    ( mode & ~S_IFMT ) | S_IFREG,
+    &IMFS_node_control_linfile,
+    sizeof( IMFS_linearfile_t ),
+    &ctx
+  );
+}
diff --git a/testsuites/libtests/shell01/init.c b/testsuites/libtests/shell01/init.c
index 57b4461a93..bc28463009 100644
--- a/testsuites/libtests/shell01/init.c
+++ b/testsuites/libtests/shell01/init.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2014, 2019 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -24,6 +24,7 @@
 #include <stdio.h>
 #include <unistd.h>
 
+#include <rtems/imfs.h>
 #include <rtems/shell.h>
 #include <rtems/userenv.h>
 
@@ -31,20 +32,23 @@
 
 const char rtems_test_name[] = "SHELL 1";
 
-static void create_file(const char *name, const char *content)
-{
-  FILE *fp;
-  int rv;
-
-  fp = fopen(name, "wx");
-  rtems_test_assert(fp != NULL);
-
-  rv = fputs(content, fp);
-  rtems_test_assert(rv == 0);
-
-  rv = fclose(fp);
-  rtems_test_assert(rv == 0);
-}
+static const char etc_passwd[] =
+  "moop:foo:1:3:blob:a::c\n"
+  "no:*:2:4::::\n"
+  "zero::3:5::::\n"
+  "shadow:x:4:6::::\n"
+  "invchroot::5:7:::/inv:\n"
+  "chroot::6:8:::/chroot:\n";
+
+static const char etc_group[] =
+  "A::1:moop,u,v,w,zero\n"
+  "B::2:moop\n"
+  "blub:bar:3:moop\n"
+  "C::4:l,m,n,moop\n"
+  "D::5:moop,moop\n"
+  "E::6:x\n"
+  "E::7:y,z\n"
+  "F::8:s,moop,t\n";
 
 static void test(void)
 {
@@ -64,27 +68,21 @@ static void test(void)
   rv = lstat("/chroot", &st_chroot);
   rtems_test_assert(rv == 0);
 
-  create_file(
+  rv = IMFS_make_linearfile(
     "/etc/passwd",
-    "moop:foo:1:3:blob:a::c\n"
-    "no:*:2:4::::\n"
-    "zero::3:5::::\n"
-    "shadow:x:4:6::::\n"
-    "invchroot::5:7:::/inv:\n"
-    "chroot::6:8:::/chroot:\n"
+    S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH,
+    etc_passwd,
+    sizeof(etc_passwd)
   );
+  rtems_test_assert(rv == 0);
 
-  create_file(
+  rv = IMFS_make_linearfile(
     "/etc/group",
-    "A::1:moop,u,v,w,zero\n"
-    "B::2:moop\n"
-    "blub:bar:3:moop\n"
-    "C::4:l,m,n,moop\n"
-    "D::5:moop,moop\n"
-    "E::6:x\n"
-    "E::7:y,z\n"
-    "F::8:s,moop,t\n"
+    S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH,
+    etc_group,
+    sizeof(etc_group)
   );
+  rtems_test_assert(rv == 0);
 
   sc = rtems_libio_set_private_env();
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-- 
2.16.4



More information about the devel mailing list