summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs/src/imfs/imfs_creat.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libfs/src/imfs/imfs_creat.c')
-rw-r--r--cpukit/libfs/src/imfs/imfs_creat.c170
1 files changed, 170 insertions, 0 deletions
diff --git a/cpukit/libfs/src/imfs/imfs_creat.c b/cpukit/libfs/src/imfs/imfs_creat.c
new file mode 100644
index 0000000000..3b602d0c14
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_creat.c
@@ -0,0 +1,170 @@
+/*
+ * IMFS_create_node()
+ *
+ * Routine to create a new in memory file system node.
+ *
+ * COPYRIGHT (c) 1989-2010.
+ * 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.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include "imfs.h"
+#include <rtems/libio_.h>
+
+/*
+ * Create an IMFS filesystem node of an arbitrary type that is NOT
+ * the root directory node.
+ */
+IMFS_jnode_t *IMFS_create_node(
+ rtems_filesystem_location_info_t *parent_loc,
+ IMFS_jnode_types_t type,
+ const char *name,
+ mode_t mode,
+ const IMFS_types_union *info
+)
+{
+ IMFS_jnode_t *node;
+ IMFS_jnode_t *parent;
+ IMFS_fs_info_t *fs_info;
+
+ /*
+ * MUST have a parent node to call this routine.
+ */
+ if ( parent_loc == NULL )
+ return NULL;
+
+ parent = parent_loc->node_access;
+ fs_info = parent_loc->mt_entry->fs_info;
+
+ /*
+ * Reject creation of FIFOs if support is disabled.
+ */
+ if ( type == IMFS_FIFO &&
+ fs_info->fifo_handlers == &rtems_filesystem_handlers_default )
+ return NULL;
+
+ /*
+ * Allocate filesystem node and fill in basic information
+ */
+ node = IMFS_allocate_node( type, name, mode & ~rtems_filesystem_umask );
+ if ( !node )
+ return NULL;
+
+ /*
+ * Set the type specific information
+ */
+ if ( type == IMFS_DIRECTORY ) {
+ rtems_chain_initialize_empty(&node->info.directory.Entries);
+ } else if ( type == IMFS_HARD_LINK ) {
+ node->info.hard_link.link_node = info->hard_link.link_node;
+ } else if ( type == IMFS_SYM_LINK ) {
+ node->info.sym_link.name = info->sym_link.name;
+ } else if ( type == IMFS_DEVICE ) {
+ node->info.device.major = info->device.major;
+ node->info.device.minor = info->device.minor;
+ } else if ( type == IMFS_LINEAR_FILE ) {
+ node->info.linearfile.size = 0;
+ node->info.linearfile.direct = 0;
+ } else if ( type == IMFS_MEMORY_FILE ) {
+ node->info.file.size = 0;
+ node->info.file.indirect = 0;
+ node->info.file.doubly_indirect = 0;
+ node->info.file.triply_indirect = 0;
+ } else if ( type == IMFS_FIFO ) {
+ node->info.fifo.pipe = NULL;
+ } else {
+ IMFS_assert(0);
+ }
+
+ /*
+ * This node MUST have a parent, so put it in that directory list.
+ */
+ node->Parent = parent;
+ node->st_ino = ++fs_info->ino_count;
+
+ rtems_chain_append( &parent->info.directory.Entries, &node->Node );
+
+ return node;
+}
+
+/*
+ * Allocate filesystem node and fill in basic information
+ */
+IMFS_jnode_t *IMFS_allocate_node(
+ IMFS_jnode_types_t type,
+ const char *name,
+ mode_t mode
+)
+{
+ IMFS_jnode_t *node;
+ struct timeval tv;
+
+ /*
+ * Allocate an IMFS jnode
+ */
+ node = calloc( 1, sizeof( IMFS_jnode_t ) );
+ if ( !node )
+ return NULL;
+
+ /*
+ * Fill in the basic information
+ */
+ node->st_nlink = 1;
+ node->type = type;
+ strncpy( node->name, name, IMFS_NAME_MAX );
+
+ /*
+ * Fill in the mode and permission information for the jnode structure.
+ */
+ node->st_mode = mode;
+ #if defined(RTEMS_POSIX_API)
+ node->st_uid = geteuid();
+ node->st_gid = getegid();
+ #else
+ node->st_uid = 0;
+ node->st_gid = 0;
+ #endif
+
+ /*
+ * Now set all the times.
+ */
+ gettimeofday( &tv, 0 );
+
+ node->stat_atime = (time_t) tv.tv_sec;
+ node->stat_mtime = (time_t) tv.tv_sec;
+ node->stat_ctime = (time_t) tv.tv_sec;
+
+ return node;
+}
+
+IMFS_jnode_t *IMFS_create_root_node(void)
+{
+ IMFS_jnode_t *node;
+
+ /*
+ * Allocate filesystem node and fill in basic information
+ */
+ node = IMFS_allocate_node( IMFS_DIRECTORY, "", (S_IFDIR | 0755) );
+ if ( !node )
+ return NULL;
+
+ /*
+ * Set the type specific information
+ *
+ * NOTE: Root node is always a directory.
+ */
+ rtems_chain_initialize_empty(&node->info.directory.Entries);
+
+ return node;
+}