source: rtems/cpukit/libfs/src/imfs/imfs_directory.c @ cf4dfc1

4.115
Last change on this file since cf4dfc1 was 924cbd4f, checked in by Sebastian Huber <sebastian.huber@…>, on 01/31/15 at 20:27:01

IMFS: Simplify ino generation

The type of ino_t is unsigned long, so it can store a pointer. Avoid a
potential integer overflow.

  • Property mode set to 100644
File size: 2.5 KB
Line 
1/**
2 * @file
3 *
4 * @brief IMFS Read Next Directory
5 * @ingroup IMFS
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-1999.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18  #include "config.h"
19#endif
20
21#include "imfs.h"
22
23#include <string.h>
24#include <dirent.h>
25
26ssize_t imfs_dir_read(
27  rtems_libio_t  *iop,
28  void           *buffer,
29  size_t          count
30)
31{
32  /*
33   *  Read up to element  iop->offset in the directory chain of the
34   *  imfs_jnode_t struct for this file descriptor.
35   */
36   const IMFS_directory_t    *dir;
37   const rtems_chain_node    *node;
38   const rtems_chain_control *entries;
39   struct dirent             *dir_ent;
40   ssize_t                    bytes_transferred;
41   off_t                      current_entry;
42   off_t                      first_entry;
43   off_t                      last_entry;
44
45   rtems_filesystem_instance_lock( &iop->pathinfo );
46
47   dir = IMFS_iop_to_directory( iop );
48   entries = &dir->Entries;
49
50   /* Move to the first of the desired directory entries */
51
52   bytes_transferred = 0;
53   first_entry = iop->offset;
54   /* protect against using sizes that are not exact multiples of the */
55   /* -dirent- size. These could result in unexpected results          */
56   last_entry = first_entry
57     + (count / sizeof( *dir_ent )) * sizeof( *dir_ent );
58
59   /* The directory was not empty so try to move to the desired entry in chain*/
60   for (
61      current_entry = 0,
62        node = rtems_chain_immutable_first( entries );
63      current_entry < last_entry
64        && !rtems_chain_is_tail( entries, node );
65      current_entry +=  sizeof( *dir_ent ),
66        node = rtems_chain_immutable_next( node )
67   ) {
68      if( current_entry >= first_entry ) {
69         const IMFS_jnode_t *imfs_node = (const IMFS_jnode_t *) node;
70
71         dir_ent = (struct dirent *) ((char *) buffer + bytes_transferred);
72
73         /* Move the entry to the return buffer */
74         dir_ent->d_off = current_entry;
75         dir_ent->d_reclen = sizeof( *dir_ent );
76         dir_ent->d_ino = IMFS_node_to_ino( imfs_node );
77         dir_ent->d_namlen = strlen( imfs_node->name );
78         memcpy( dir_ent->d_name, imfs_node->name, dir_ent->d_namlen + 1 );
79
80         iop->offset += sizeof( *dir_ent );
81         bytes_transferred += (ssize_t) sizeof( *dir_ent );
82      }
83   }
84
85   rtems_filesystem_instance_unlock( &iop->pathinfo );
86
87   return bytes_transferred;
88}
Note: See TracBrowser for help on using the repository browser.