mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-26 00:14:03 +08:00
IMFS: Add CONFIGURE_IMFS_DISABLE_READDIR
This commit is contained in:
@@ -42,13 +42,15 @@ libimfs_a_SOURCES =
|
||||
|
||||
libimfs_a_SOURCES += src/imfs/deviceio.c \
|
||||
src/imfs/imfs_chown.c src/imfs/imfs_config.c \
|
||||
src/imfs/imfs_creat.c src/imfs/imfs_directory.c \
|
||||
src/imfs/imfs_creat.c \
|
||||
src/imfs/imfs_eval.c src/imfs/imfs_fchmod.c \
|
||||
src/imfs/imfs_dir.c \
|
||||
src/imfs/imfs_dir_default.c \
|
||||
src/imfs/imfs_dir_minimal.c \
|
||||
src/imfs/imfs_fifo.c \
|
||||
src/imfs/imfs_make_generic_node.c \
|
||||
src/imfs/imfs_fsunmount.c \
|
||||
src/imfs/imfs_handlers_device.c \
|
||||
src/imfs/imfs_handlers_directory.c \
|
||||
src/imfs/imfs_init.c \
|
||||
src/imfs/imfs_initsupp.c src/imfs/imfs_link.c src/imfs/imfs_load_tar.c \
|
||||
src/imfs/imfs_linfile.c \
|
||||
|
||||
@@ -135,6 +135,11 @@ IMFS_jnode_t *IMFS_node_initialize_default(
|
||||
void *arg
|
||||
);
|
||||
|
||||
IMFS_jnode_t *IMFS_node_initialize_directory(
|
||||
IMFS_jnode_t *node,
|
||||
void *arg
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Returns the node and sets the generic node context.
|
||||
*
|
||||
@@ -179,6 +184,8 @@ IMFS_jnode_t *IMFS_node_remove_default(
|
||||
IMFS_jnode_t *node
|
||||
);
|
||||
|
||||
IMFS_jnode_t *IMFS_node_remove_directory( IMFS_jnode_t *node );
|
||||
|
||||
/**
|
||||
* @brief Destroys an IMFS node.
|
||||
*
|
||||
@@ -384,7 +391,8 @@ typedef struct {
|
||||
* Shared Data
|
||||
*/
|
||||
|
||||
extern const IMFS_mknod_control IMFS_mknod_control_directory;
|
||||
extern const IMFS_mknod_control IMFS_mknod_control_dir_default;
|
||||
extern const IMFS_mknod_control IMFS_mknod_control_dir_minimal;
|
||||
extern const IMFS_mknod_control IMFS_mknod_control_device;
|
||||
extern const IMFS_mknod_control IMFS_mknod_control_memfile;
|
||||
extern const IMFS_node_control IMFS_node_control_linfile;
|
||||
@@ -699,26 +707,6 @@ extern int IMFS_unmount(
|
||||
rtems_filesystem_mount_table_entry_t *mt_entry /* IN */
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Read the next directory of the IMFS.
|
||||
*
|
||||
* This routine will read the next directory entry based on the directory
|
||||
* offset. The offset should be equal to -n- time the size of an individual
|
||||
* dirent structure. If n is not an integer multiple of the sizeof a
|
||||
* dirent structure, an integer division will be performed to determine
|
||||
* directory entry that will be returned in the buffer. Count should reflect
|
||||
* -m- times the sizeof dirent bytes to be placed in the buffer.
|
||||
* If there are not -m- dirent elements from the current directory position
|
||||
* to the end of the exisiting file, the remaining entries will be placed in
|
||||
* the buffer and the returned value will be equal to -m actual- times the
|
||||
* size of a directory entry.
|
||||
*/
|
||||
extern ssize_t imfs_dir_read(
|
||||
rtems_libio_t *iop, /* IN */
|
||||
void *buffer, /* IN */
|
||||
size_t count /* IN */
|
||||
);
|
||||
|
||||
/**
|
||||
* @name IMFS Memory File Handlers
|
||||
*
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup IMFS
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* 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.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "imfs.h"
|
||||
|
||||
IMFS_jnode_t *IMFS_node_initialize_directory(
|
||||
IMFS_jnode_t *node,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
IMFS_directory_t *dir = (IMFS_directory_t *) node;
|
||||
|
||||
rtems_chain_initialize_empty( &dir->Entries );
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool IMFS_is_mount_point( const IMFS_directory_t *dir )
|
||||
{
|
||||
return dir->mt_fs != NULL;
|
||||
}
|
||||
|
||||
IMFS_jnode_t *IMFS_node_remove_directory( IMFS_jnode_t *node )
|
||||
{
|
||||
IMFS_directory_t *dir = (IMFS_directory_t *) node;
|
||||
|
||||
if ( !rtems_chain_is_empty( &dir->Entries ) ) {
|
||||
errno = ENOTEMPTY;
|
||||
dir = NULL;
|
||||
} else if ( IMFS_is_mount_point( dir ) ) {
|
||||
errno = EBUSY;
|
||||
dir = NULL;
|
||||
}
|
||||
|
||||
return &dir->Node;
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief IMFS Read Next Directory
|
||||
* @ingroup IMFS
|
||||
*/
|
||||
|
||||
@@ -20,10 +19,10 @@
|
||||
|
||||
#include "imfs.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
|
||||
ssize_t imfs_dir_read(
|
||||
static ssize_t IMFS_dir_read(
|
||||
rtems_libio_t *iop,
|
||||
void *buffer,
|
||||
size_t count
|
||||
@@ -86,3 +85,59 @@ ssize_t imfs_dir_read(
|
||||
|
||||
return bytes_transferred;
|
||||
}
|
||||
|
||||
static size_t IMFS_directory_size( const IMFS_jnode_t *node )
|
||||
{
|
||||
size_t size = 0;
|
||||
const IMFS_directory_t *dir = (const IMFS_directory_t *) node;
|
||||
const rtems_chain_control *chain = &dir->Entries;
|
||||
const rtems_chain_node *current = rtems_chain_immutable_first( chain );
|
||||
const rtems_chain_node *tail = rtems_chain_immutable_tail( chain );
|
||||
|
||||
while ( current != tail ) {
|
||||
size += sizeof( struct dirent );
|
||||
current = rtems_chain_immutable_next( current );
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int IMFS_stat_directory(
|
||||
const rtems_filesystem_location_info_t *loc,
|
||||
struct stat *buf
|
||||
)
|
||||
{
|
||||
const IMFS_jnode_t *node = loc->node_access;
|
||||
|
||||
buf->st_size = IMFS_directory_size( node );
|
||||
|
||||
return IMFS_stat( loc, buf );
|
||||
}
|
||||
|
||||
static const rtems_filesystem_file_handlers_r IMFS_dir_default_handlers = {
|
||||
.open_h = rtems_filesystem_default_open,
|
||||
.close_h = rtems_filesystem_default_close,
|
||||
.read_h = IMFS_dir_read,
|
||||
.write_h = rtems_filesystem_default_write,
|
||||
.ioctl_h = rtems_filesystem_default_ioctl,
|
||||
.lseek_h = rtems_filesystem_default_lseek_directory,
|
||||
.fstat_h = IMFS_stat_directory,
|
||||
.ftruncate_h = rtems_filesystem_default_ftruncate_directory,
|
||||
.fsync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
|
||||
.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
|
||||
.fcntl_h = rtems_filesystem_default_fcntl,
|
||||
.kqfilter_h = rtems_filesystem_default_kqfilter,
|
||||
.poll_h = rtems_filesystem_default_poll,
|
||||
.readv_h = rtems_filesystem_default_readv,
|
||||
.writev_h = rtems_filesystem_default_writev
|
||||
};
|
||||
|
||||
const IMFS_mknod_control IMFS_mknod_control_dir_default = {
|
||||
{
|
||||
.handlers = &IMFS_dir_default_handlers,
|
||||
.node_initialize = IMFS_node_initialize_directory,
|
||||
.node_remove = IMFS_node_remove_directory,
|
||||
.node_destroy = IMFS_node_destroy_default
|
||||
},
|
||||
.node_size = sizeof( IMFS_directory_t )
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup IMFS
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* 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.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "imfs.h"
|
||||
|
||||
static const rtems_filesystem_file_handlers_r IMFS_dir_minimal_handlers = {
|
||||
.open_h = rtems_filesystem_default_open,
|
||||
.close_h = rtems_filesystem_default_close,
|
||||
.read_h = rtems_filesystem_default_read,
|
||||
.write_h = rtems_filesystem_default_write,
|
||||
.ioctl_h = rtems_filesystem_default_ioctl,
|
||||
.lseek_h = rtems_filesystem_default_lseek_directory,
|
||||
.fstat_h = IMFS_stat,
|
||||
.ftruncate_h = rtems_filesystem_default_ftruncate_directory,
|
||||
.fsync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
|
||||
.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
|
||||
.fcntl_h = rtems_filesystem_default_fcntl,
|
||||
.kqfilter_h = rtems_filesystem_default_kqfilter,
|
||||
.poll_h = rtems_filesystem_default_poll,
|
||||
.readv_h = rtems_filesystem_default_readv,
|
||||
.writev_h = rtems_filesystem_default_writev
|
||||
};
|
||||
|
||||
const IMFS_mknod_control IMFS_mknod_control_dir_minimal = {
|
||||
{
|
||||
.handlers = &IMFS_dir_minimal_handlers,
|
||||
.node_initialize = IMFS_node_initialize_directory,
|
||||
.node_remove = IMFS_node_remove_directory,
|
||||
.node_destroy = IMFS_node_destroy_default
|
||||
},
|
||||
.node_size = sizeof( IMFS_directory_t )
|
||||
};
|
||||
@@ -1,113 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief Operations Table for Directories
|
||||
* @ingroup IMFS
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* 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.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "imfs.h"
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
static size_t IMFS_directory_size( const IMFS_jnode_t *node )
|
||||
{
|
||||
size_t size = 0;
|
||||
const IMFS_directory_t *dir = (const IMFS_directory_t *) node;
|
||||
const rtems_chain_control *chain = &dir->Entries;
|
||||
const rtems_chain_node *current = rtems_chain_immutable_first( chain );
|
||||
const rtems_chain_node *tail = rtems_chain_immutable_tail( chain );
|
||||
|
||||
while ( current != tail ) {
|
||||
size += sizeof( struct dirent );
|
||||
current = rtems_chain_immutable_next( current );
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int IMFS_stat_directory(
|
||||
const rtems_filesystem_location_info_t *loc,
|
||||
struct stat *buf
|
||||
)
|
||||
{
|
||||
const IMFS_jnode_t *node = loc->node_access;
|
||||
|
||||
buf->st_size = IMFS_directory_size( node );
|
||||
|
||||
return IMFS_stat( loc, buf );
|
||||
}
|
||||
|
||||
static const rtems_filesystem_file_handlers_r IMFS_directory_handlers = {
|
||||
.open_h = rtems_filesystem_default_open,
|
||||
.close_h = rtems_filesystem_default_close,
|
||||
.read_h = imfs_dir_read,
|
||||
.write_h = rtems_filesystem_default_write,
|
||||
.ioctl_h = rtems_filesystem_default_ioctl,
|
||||
.lseek_h = rtems_filesystem_default_lseek_directory,
|
||||
.fstat_h = IMFS_stat_directory,
|
||||
.ftruncate_h = rtems_filesystem_default_ftruncate_directory,
|
||||
.fsync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
|
||||
.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
|
||||
.fcntl_h = rtems_filesystem_default_fcntl,
|
||||
.kqfilter_h = rtems_filesystem_default_kqfilter,
|
||||
.poll_h = rtems_filesystem_default_poll,
|
||||
.readv_h = rtems_filesystem_default_readv,
|
||||
.writev_h = rtems_filesystem_default_writev
|
||||
};
|
||||
|
||||
static IMFS_jnode_t *IMFS_node_initialize_directory(
|
||||
IMFS_jnode_t *node,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
IMFS_directory_t *dir = (IMFS_directory_t *) node;
|
||||
|
||||
rtems_chain_initialize_empty( &dir->Entries );
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool IMFS_is_mount_point( const IMFS_directory_t *dir )
|
||||
{
|
||||
return dir->mt_fs != NULL;
|
||||
}
|
||||
|
||||
static IMFS_jnode_t *IMFS_node_remove_directory(
|
||||
IMFS_jnode_t *node
|
||||
)
|
||||
{
|
||||
IMFS_directory_t *dir = (IMFS_directory_t *) node;
|
||||
|
||||
if ( !rtems_chain_is_empty( &dir->Entries ) ) {
|
||||
errno = ENOTEMPTY;
|
||||
dir = NULL;
|
||||
} else if ( IMFS_is_mount_point( dir ) ) {
|
||||
errno = EBUSY;
|
||||
dir = NULL;
|
||||
}
|
||||
|
||||
return &dir->Node;
|
||||
}
|
||||
|
||||
const IMFS_mknod_control IMFS_mknod_control_directory = {
|
||||
{
|
||||
.handlers = &IMFS_directory_handlers,
|
||||
.node_initialize = IMFS_node_initialize_directory,
|
||||
.node_remove = IMFS_node_remove_directory,
|
||||
.node_destroy = IMFS_node_destroy_default
|
||||
},
|
||||
.node_size = sizeof( IMFS_directory_t )
|
||||
};
|
||||
@@ -48,7 +48,7 @@ static const rtems_filesystem_operations_table IMFS_ops = {
|
||||
};
|
||||
|
||||
static const IMFS_mknod_controls IMFS_default_mknod_controls = {
|
||||
.directory = &IMFS_mknod_control_directory,
|
||||
.directory = &IMFS_mknod_control_dir_default,
|
||||
.device = &IMFS_mknod_control_device,
|
||||
.file = &IMFS_mknod_control_memfile,
|
||||
.fifo = &IMFS_mknod_control_enosys
|
||||
|
||||
@@ -619,7 +619,11 @@ const rtems_libio_helper rtems_fs_init_helper =
|
||||
};
|
||||
|
||||
static const IMFS_mknod_controls _Configure_IMFS_mknod_controls = {
|
||||
&IMFS_mknod_control_directory,
|
||||
#ifdef CONFIGURE_IMFS_DISABLE_READDIR
|
||||
&IMFS_mknod_control_dir_minimal,
|
||||
#else
|
||||
&IMFS_mknod_control_dir_default,
|
||||
#endif
|
||||
&IMFS_mknod_control_device,
|
||||
#ifdef CONFIGURE_IMFS_DISABLE_MKNOD_FILE
|
||||
&IMFS_mknod_control_enosys,
|
||||
|
||||
@@ -2894,6 +2894,33 @@ This is not defined by default.
|
||||
In case this configuration option is defined, then the support to rename nodes
|
||||
is disabled in the root IMFS.
|
||||
|
||||
@c
|
||||
@c === CONFIGURE_IMFS_DISABLE_READDIR ===
|
||||
@c
|
||||
@subsection Disable Directory Read Support of Root IMFS
|
||||
|
||||
@findex CONFIGURE_IMFS_DISABLE_READDIR
|
||||
|
||||
@table @b
|
||||
@item CONSTANT:
|
||||
@code{CONFIGURE_IMFS_DISABLE_READDIR}
|
||||
|
||||
@item DATA TYPE:
|
||||
Boolean feature macro.
|
||||
|
||||
@item RANGE:
|
||||
Defined or undefined.
|
||||
|
||||
@item DEFAULT VALUE:
|
||||
This is not defined by default.
|
||||
|
||||
@end table
|
||||
|
||||
@subheading DESCRIPTION:
|
||||
In case this configuration option is defined, then the support to read a
|
||||
directory is disabled in the root IMFS. It is still possible to open nodes in
|
||||
a directory.
|
||||
|
||||
@c
|
||||
@c === CONFIGURE_IMFS_DISABLE_MOUNT ===
|
||||
@c
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "tmacros.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
@@ -46,6 +47,9 @@ static void Init(rtems_task_argument arg)
|
||||
const char *fifo = "fifo";
|
||||
int rv;
|
||||
int fd;
|
||||
DIR *dirp;
|
||||
struct dirent *dire;
|
||||
struct stat st;
|
||||
|
||||
TEST_BEGIN();
|
||||
|
||||
@@ -88,6 +92,21 @@ static void Init(rtems_task_argument arg)
|
||||
rtems_test_assert(rv == -1);
|
||||
rtems_test_assert(errno == ENOSYS);
|
||||
|
||||
dirp = opendir(mnt);
|
||||
rtems_test_assert(dirp != NULL);
|
||||
|
||||
errno = 0;
|
||||
dire = readdir(dirp);
|
||||
rtems_test_assert(dire == NULL);
|
||||
rtems_test_assert(errno == ENOTSUP);
|
||||
|
||||
rv = closedir(dirp);
|
||||
rtems_test_assert(rv == 0);
|
||||
|
||||
rv = stat(mnt, &st);
|
||||
rtems_test_assert(rv == 0);
|
||||
rtems_test_assert(st.st_size == 0);
|
||||
|
||||
errno = 0;
|
||||
rv = mount(
|
||||
"",
|
||||
@@ -145,6 +164,7 @@ static void Init(rtems_task_argument arg)
|
||||
#define CONFIGURE_IMFS_DISABLE_MKNOD_FILE
|
||||
#define CONFIGURE_IMFS_DISABLE_MOUNT
|
||||
#define CONFIGURE_IMFS_DISABLE_RENAME
|
||||
#define CONFIGURE_IMFS_DISABLE_READDIR
|
||||
#define CONFIGURE_IMFS_DISABLE_RMNOD
|
||||
#define CONFIGURE_IMFS_DISABLE_SYMLINK
|
||||
#define CONFIGURE_IMFS_DISABLE_UTIME
|
||||
|
||||
Reference in New Issue
Block a user