summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs/src/imfs/imfs_handlers_link.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libfs/src/imfs/imfs_handlers_link.c')
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_link.c69
1 files changed, 65 insertions, 4 deletions
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_link.c b/cpukit/libfs/src/imfs/imfs_handlers_link.c
index fd68f77eef..08dddb701d 100644
--- a/cpukit/libfs/src/imfs/imfs_handlers_link.c
+++ b/cpukit/libfs/src/imfs/imfs_handlers_link.c
@@ -17,11 +17,9 @@
#include "imfs.h"
-/*
- * Handler table for IMFS device nodes
- */
+#include <stdlib.h>
-const rtems_filesystem_file_handlers_r IMFS_link_handlers = {
+static const rtems_filesystem_file_handlers_r IMFS_link_handlers = {
rtems_filesystem_default_open,
rtems_filesystem_default_close,
rtems_filesystem_default_read,
@@ -34,3 +32,66 @@ const rtems_filesystem_file_handlers_r IMFS_link_handlers = {
rtems_filesystem_default_fsync_or_fdatasync,
rtems_filesystem_default_fcntl
};
+
+static IMFS_jnode_t *IMFS_node_initialize_hard_link(
+ IMFS_jnode_t *node,
+ const IMFS_types_union *info
+)
+{
+ node->info.hard_link.link_node = info->hard_link.link_node;
+
+ return node;
+}
+
+static IMFS_jnode_t *IMFS_node_remove_hard_link(
+ IMFS_jnode_t *node,
+ const IMFS_jnode_t *root_node
+)
+{
+ IMFS_jnode_t *target = node->info.hard_link.link_node;
+
+ if ( target->st_nlink == 1) {
+ target = (*target->control->node_remove)( target, root_node );
+ if ( target == NULL ) {
+ node = NULL;
+ }
+ } else {
+ --target->st_nlink;
+ IMFS_update_ctime( target );
+ }
+
+ return node;
+}
+
+const IMFS_node_control IMFS_node_control_hard_link = {
+ .imfs_type = IMFS_HARD_LINK,
+ .handlers = &IMFS_link_handlers,
+ .node_initialize = IMFS_node_initialize_hard_link,
+ .node_remove = IMFS_node_remove_hard_link,
+ .node_destroy = IMFS_node_destroy_default
+};
+
+static IMFS_jnode_t *IMFS_node_initialize_sym_link(
+ IMFS_jnode_t *node,
+ const IMFS_types_union *info
+)
+{
+ node->info.sym_link.name = info->sym_link.name;
+
+ return node;
+}
+
+static IMFS_jnode_t *IMFS_node_destroy_sym_link( IMFS_jnode_t *node )
+{
+ free( node->info.sym_link.name );
+
+ return node;
+}
+
+const IMFS_node_control IMFS_node_control_sym_link = {
+ .imfs_type = IMFS_SYM_LINK,
+ .handlers = &IMFS_link_handlers,
+ .node_initialize = IMFS_node_initialize_sym_link,
+ .node_remove = IMFS_node_remove_default,
+ .node_destroy = IMFS_node_destroy_sym_link
+};