source: rtems/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c @ 3c96bee

4.115
Last change on this file since 3c96bee was ff1becb, checked in by Joel Sherrill <joel.sherrill@…>, on 01/10/13 at 19:22:57

rfs: Doxygen group cannot have a dash in it

Change rtems-rfs to rtems_rfs

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/**
2 * @file
3 *
4 * @brief RTEMS RFS Directory Access Routines
5 * @ingroup rtems_rfs
6 */
7/*
8 *  COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
9 *
10 *  The license and distribution terms for this file may be
11 *  found in the file LICENSE in this distribution or at
12 *  http://www.rtems.com/license/LICENSE.
13 */
14
15#if HAVE_CONFIG_H
16#include "config.h"
17#endif
18
19#include <inttypes.h>
20
21#include <sys/types.h>
22#include <sys/stat.h>
23#include <fcntl.h>
24#include <stdlib.h>
25#include <stdio.h>
26#include <unistd.h>
27
28#include <rtems/rfs/rtems-rfs-dir.h>
29#include <rtems/rfs/rtems-rfs-link.h>
30#include "rtems-rfs-rtems.h"
31
32/**
33 * This rountine will verify that the node being opened as a directory is in
34 * fact a directory node. If it is then the offset into the directory will be
35 * set to 0 to position to the first directory entry.
36 */
37static int
38rtems_rfs_rtems_dir_open (rtems_libio_t* iop,
39                          const char*    pathname,
40                          int            oflag,
41                          mode_t         mode)
42{
43  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo);
44  rtems_rfs_ino          ino = rtems_rfs_rtems_get_iop_ino (iop);
45  rtems_rfs_inode_handle inode;
46  int                    rc;
47
48  rtems_rfs_rtems_lock (fs);
49
50  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
51  if (rc)
52  {
53    rtems_rfs_rtems_unlock (fs);
54    return rtems_rfs_rtems_error ("dir_open: opening inode", rc);
55  }
56
57  if (!RTEMS_RFS_S_ISDIR (rtems_rfs_inode_get_mode (&inode)))
58  {
59    rtems_rfs_inode_close (fs, &inode);
60    rtems_rfs_rtems_unlock (fs);
61    return rtems_rfs_rtems_error ("dir_open: not dir", ENOTDIR);
62  }
63
64  iop->offset = 0;
65
66  rtems_rfs_inode_close (fs, &inode);
67  rtems_rfs_rtems_unlock (fs);
68  return 0;
69}
70
71/**
72 * This routine will be called by the generic close routine to cleanup any
73 * resources that have been allocated for the management of the file
74 *
75 * @param iop
76 * @retval 0 Always no error.
77 */
78static int
79rtems_rfs_rtems_dir_close (rtems_libio_t* iop)
80{
81  /*
82   * The RFS does not hold any resources. Nothing to do.
83   */
84  return 0;
85}
86
87/**
88 * This routine will read the next directory entry based on the directory
89 * offset. The offset should be equal to -n- time the size of an individual
90 * dirent structure. If n is not an integer multiple of the sizeof a dirent
91 * structure, an integer division will be performed to determine directory
92 * entry that will be returned in the buffer. Count should reflect -m- times
93 * the sizeof dirent bytes to be placed in the buffer.  If there are not -m-
94 * dirent elements from the current directory position to the end of the
95 * exisiting file, the remaining entries will be placed in the buffer and the
96 * returned value will be equal to -m actual- times the size of a directory
97 * entry.
98 */
99static ssize_t
100rtems_rfs_rtems_dir_read (rtems_libio_t* iop,
101                          void*          buffer,
102                          size_t         count)
103{
104  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo);
105  rtems_rfs_ino          ino = rtems_rfs_rtems_get_iop_ino (iop);
106  rtems_rfs_inode_handle inode;
107  struct dirent*         dirent;
108  ssize_t                bytes_transferred;
109  int                    d;
110  int                    rc;
111
112  count  = count / sizeof (struct dirent);
113  dirent = buffer;
114
115  rtems_rfs_rtems_lock (fs);
116
117  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
118  if (rc)
119  {
120    rtems_rfs_rtems_unlock (fs);
121    return rtems_rfs_rtems_error ("dir_read: read inode", rc);
122  }
123
124  bytes_transferred = 0;
125
126  for (d = 0; d < count; d++, dirent++)
127  {
128    size_t size;
129    rc = rtems_rfs_dir_read (fs, &inode, iop->offset, dirent, &size);
130    if (rc == ENOENT)
131    {
132      rc = 0;
133      break;
134    }
135    if (rc > 0)
136    {
137      bytes_transferred = rtems_rfs_rtems_error ("dir_read: dir read", rc);
138      break;
139    }
140    iop->offset += size;
141    bytes_transferred += sizeof (struct dirent);
142  }
143
144  rtems_rfs_inode_close (fs, &inode);
145  rtems_rfs_rtems_unlock (fs);
146
147  return bytes_transferred;
148}
149
150/*
151 *  Set of operations handlers for operations on directories.
152 */
153
154const rtems_filesystem_file_handlers_r rtems_rfs_rtems_dir_handlers = {
155  .open_h      = rtems_rfs_rtems_dir_open,
156  .close_h     = rtems_rfs_rtems_dir_close,
157  .read_h      = rtems_rfs_rtems_dir_read,
158  .write_h     = rtems_filesystem_default_write,
159  .ioctl_h     = rtems_filesystem_default_ioctl,
160  .lseek_h     = rtems_filesystem_default_lseek_directory,
161  .fstat_h     = rtems_rfs_rtems_fstat,
162  .ftruncate_h = rtems_filesystem_default_ftruncate_directory,
163  .fsync_h     = rtems_filesystem_default_fsync_or_fdatasync,
164  .fdatasync_h = rtems_rfs_rtems_fdatasync,
165  .fcntl_h     = rtems_filesystem_default_fcntl
166};
Note: See TracBrowser for help on using the repository browser.