source: rtems/cpukit/libfs/src/imfs/imfs_dir_default.c

Last change on this file was 67a5936, checked in by Joel Sherrill <joel@…>, on 03/18/22 at 14:43:02

cpukit/libfs/src/imfs: Change license to BSD-2

Updates #3053.

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup IMFS
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-1999.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 */
34
35#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
39#include <rtems/imfs.h>
40
41#include <sys/param.h>
42#include <dirent.h>
43#include <string.h>
44
45static ssize_t IMFS_dir_read(
46  rtems_libio_t  *iop,
47  void           *buffer,
48  size_t          count
49)
50{
51  /*
52   *  Read up to element  iop->offset in the directory chain of the
53   *  imfs_jnode_t struct for this file descriptor.
54   */
55   const IMFS_directory_t    *dir;
56   const rtems_chain_node    *node;
57   const rtems_chain_control *entries;
58   struct dirent             *dir_ent;
59   ssize_t                    bytes_transferred;
60   off_t                      current_entry;
61   off_t                      first_entry;
62   off_t                      last_entry;
63
64   rtems_filesystem_instance_lock( &iop->pathinfo );
65
66   dir = IMFS_iop_to_directory( iop );
67   entries = &dir->Entries;
68
69   /* Move to the first of the desired directory entries */
70
71   bytes_transferred = 0;
72   first_entry = iop->offset;
73   /* protect against using sizes that are not exact multiples of the */
74   /* -dirent- size. These could result in unexpected results          */
75   last_entry = first_entry
76     + (count / sizeof( *dir_ent )) * sizeof( *dir_ent );
77
78   /* The directory was not empty so try to move to the desired entry in chain*/
79   for (
80      current_entry = 0,
81        node = rtems_chain_immutable_first( entries );
82      current_entry < last_entry
83        && !rtems_chain_is_tail( entries, node );
84      current_entry +=  sizeof( *dir_ent ),
85        node = rtems_chain_immutable_next( node )
86   ) {
87      if( current_entry >= first_entry ) {
88         const IMFS_jnode_t *imfs_node = (const IMFS_jnode_t *) node;
89
90         dir_ent = (struct dirent *) ((char *) buffer + bytes_transferred);
91
92         /* Move the entry to the return buffer */
93         dir_ent->d_off = current_entry;
94         dir_ent->d_reclen = sizeof( *dir_ent );
95         dir_ent->d_ino = IMFS_node_to_ino( imfs_node );
96#ifdef DT_DIR
97         dir_ent->d_type = IFTODT( imfs_node->st_mode );
98#endif
99         dir_ent->d_namlen =
100           MIN( imfs_node->namelen, sizeof( dir_ent->d_name ) - 1 );
101         dir_ent->d_name[ dir_ent->d_namlen ] = '\0';
102         memcpy( dir_ent->d_name, imfs_node->name, dir_ent->d_namlen );
103
104         iop->offset += sizeof( *dir_ent );
105         bytes_transferred += (ssize_t) sizeof( *dir_ent );
106      }
107   }
108
109   rtems_filesystem_instance_unlock( &iop->pathinfo );
110
111   return bytes_transferred;
112}
113
114static size_t IMFS_directory_size( const IMFS_jnode_t *node )
115{
116  size_t size = 0;
117  const IMFS_directory_t *dir = (const IMFS_directory_t *) node;
118  const rtems_chain_control *chain = &dir->Entries;
119  const rtems_chain_node *current = rtems_chain_immutable_first( chain );
120  const rtems_chain_node *tail = rtems_chain_immutable_tail( chain );
121
122  while ( current != tail ) {
123    size += sizeof( struct dirent );
124    current = rtems_chain_immutable_next( current );
125  }
126
127  return size;
128}
129
130static int IMFS_stat_directory(
131  const rtems_filesystem_location_info_t *loc,
132  struct stat *buf
133)
134{
135  const IMFS_jnode_t *node = loc->node_access;
136
137  buf->st_size = IMFS_directory_size( node );
138
139  return IMFS_stat( loc, buf );
140}
141
142static const rtems_filesystem_file_handlers_r IMFS_dir_default_handlers = {
143  .open_h = rtems_filesystem_default_open,
144  .close_h = rtems_filesystem_default_close,
145  .read_h = IMFS_dir_read,
146  .write_h = rtems_filesystem_default_write,
147  .ioctl_h = rtems_filesystem_default_ioctl,
148  .lseek_h = rtems_filesystem_default_lseek_directory,
149  .fstat_h = IMFS_stat_directory,
150  .ftruncate_h = rtems_filesystem_default_ftruncate_directory,
151  .fsync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
152  .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
153  .fcntl_h = rtems_filesystem_default_fcntl,
154  .kqfilter_h = rtems_filesystem_default_kqfilter,
155  .mmap_h = rtems_filesystem_default_mmap,
156  .poll_h = rtems_filesystem_default_poll,
157  .readv_h = rtems_filesystem_default_readv,
158  .writev_h = rtems_filesystem_default_writev
159};
160
161const IMFS_mknod_control IMFS_mknod_control_dir_default = {
162  {
163    .handlers = &IMFS_dir_default_handlers,
164    .node_initialize = IMFS_node_initialize_directory,
165    .node_remove = IMFS_node_remove_directory,
166    .node_destroy = IMFS_node_destroy_default
167  },
168  .node_size = sizeof( IMFS_directory_t )
169};
Note: See TracBrowser for help on using the repository browser.