File indexing completed on 2025-05-11 08:24:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #ifdef HAVE_CONFIG_H
0036 #include "config.h"
0037 #endif
0038
0039 #include <rtems/imfs.h>
0040
0041 #include <sys/param.h>
0042 #include <dirent.h>
0043 #include <string.h>
0044
0045 static ssize_t IMFS_dir_read(
0046 rtems_libio_t *iop,
0047 void *buffer,
0048 size_t count
0049 )
0050 {
0051
0052
0053
0054
0055 const IMFS_directory_t *dir;
0056 const rtems_chain_node *node;
0057 const rtems_chain_control *entries;
0058 struct dirent *dir_ent;
0059 ssize_t bytes_transferred;
0060 off_t current_entry;
0061 off_t first_entry;
0062 off_t last_entry;
0063
0064 rtems_filesystem_instance_lock( &iop->pathinfo );
0065
0066 dir = IMFS_iop_to_directory( iop );
0067 entries = &dir->Entries;
0068
0069
0070
0071 bytes_transferred = 0;
0072 first_entry = iop->offset;
0073
0074
0075 last_entry = first_entry
0076 + (count / sizeof( *dir_ent )) * sizeof( *dir_ent );
0077
0078
0079 for (
0080 current_entry = 0,
0081 node = rtems_chain_immutable_first( entries );
0082 current_entry < last_entry
0083 && !rtems_chain_is_tail( entries, node );
0084 current_entry += sizeof( *dir_ent ),
0085 node = rtems_chain_immutable_next( node )
0086 ) {
0087 if( current_entry >= first_entry ) {
0088 const IMFS_jnode_t *imfs_node = (const IMFS_jnode_t *) node;
0089
0090 dir_ent = (struct dirent *) ((char *) buffer + bytes_transferred);
0091
0092
0093 dir_ent->d_off = current_entry;
0094 dir_ent->d_reclen = sizeof( *dir_ent );
0095 dir_ent->d_ino = IMFS_node_to_ino( imfs_node );
0096 #ifdef DT_DIR
0097 dir_ent->d_type = IFTODT( imfs_node->st_mode );
0098 #endif
0099 dir_ent->d_namlen =
0100 MIN( imfs_node->namelen, sizeof( dir_ent->d_name ) - 1 );
0101 dir_ent->d_name[ dir_ent->d_namlen ] = '\0';
0102 memcpy( dir_ent->d_name, imfs_node->name, dir_ent->d_namlen );
0103
0104 iop->offset += sizeof( *dir_ent );
0105 bytes_transferred += (ssize_t) sizeof( *dir_ent );
0106 }
0107 }
0108
0109 rtems_filesystem_instance_unlock( &iop->pathinfo );
0110
0111 return bytes_transferred;
0112 }
0113
0114 static size_t IMFS_directory_size( const IMFS_jnode_t *node )
0115 {
0116 size_t size = 0;
0117 const IMFS_directory_t *dir = (const IMFS_directory_t *) node;
0118 const rtems_chain_control *chain = &dir->Entries;
0119 const rtems_chain_node *current = rtems_chain_immutable_first( chain );
0120 const rtems_chain_node *tail = rtems_chain_immutable_tail( chain );
0121
0122 while ( current != tail ) {
0123 size += sizeof( struct dirent );
0124 current = rtems_chain_immutable_next( current );
0125 }
0126
0127 return size;
0128 }
0129
0130 static int IMFS_stat_directory(
0131 const rtems_filesystem_location_info_t *loc,
0132 struct stat *buf
0133 )
0134 {
0135 const IMFS_jnode_t *node = loc->node_access;
0136
0137 buf->st_size = IMFS_directory_size( node );
0138
0139 return IMFS_stat( loc, buf );
0140 }
0141
0142 static const rtems_filesystem_file_handlers_r IMFS_dir_default_handlers = {
0143 .open_h = rtems_filesystem_default_open,
0144 .close_h = rtems_filesystem_default_close,
0145 .read_h = IMFS_dir_read,
0146 .write_h = rtems_filesystem_default_write,
0147 .ioctl_h = rtems_filesystem_default_ioctl,
0148 .lseek_h = rtems_filesystem_default_lseek_directory,
0149 .fstat_h = IMFS_stat_directory,
0150 .ftruncate_h = rtems_filesystem_default_ftruncate_directory,
0151 .fsync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
0152 .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
0153 .fcntl_h = rtems_filesystem_default_fcntl,
0154 .kqfilter_h = rtems_filesystem_default_kqfilter,
0155 .mmap_h = rtems_filesystem_default_mmap,
0156 .poll_h = rtems_filesystem_default_poll,
0157 .readv_h = rtems_filesystem_default_readv,
0158 .writev_h = rtems_filesystem_default_writev
0159 };
0160
0161 const IMFS_mknod_control IMFS_mknod_control_dir_default = {
0162 {
0163 .handlers = &IMFS_dir_default_handlers,
0164 .node_initialize = IMFS_node_initialize_directory,
0165 .node_remove = IMFS_node_remove_directory,
0166 .node_destroy = IMFS_node_destroy_default
0167 },
0168 .node_size = sizeof( IMFS_directory_t )
0169 };