diff options
Diffstat (limited to 'cpukit/libfs/src/imfs/imfs_handlers_link.c')
-rw-r--r-- | cpukit/libfs/src/imfs/imfs_handlers_link.c | 69 |
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 +}; |