source: rtems/c/src/libfs/src/imfs/imfs_directory.c @ 556ea0e3

4.104.114.84.95
Last change on this file since 556ea0e3 was 556ea0e3, checked in by Joel Sherrill <joel.sherrill@…>, on 05/27/99 at 16:12:20

Removed usage of printf.

  • Property mode set to 100644
File size: 7.9 KB
Line 
1/*
2 *  XXX
3 *
4 *  COPYRIGHT (c) 1989-1998.
5 *  On-Line Applications Research Corporation (OAR).
6 *  Copyright assigned to U.S. Government, 1994.
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.OARcorp.com/rtems/license.html.
11 *
12 *  $Id$
13 */
14
15#include <sys/types.h>
16#include <sys/stat.h>
17#include <chain.h>
18#include <fcntl.h>
19#include <errno.h>
20#include <stdlib.h>
21#include <stdio.h>
22#include <string.h>
23#include <assert.h>
24#include <dirent.h>
25
26#include "imfs.h"
27#include "libio_.h"
28
29long getdents(
30  int dd_fd,
31  char *dd_buf,
32  int dd_len
33);
34
35/* -----------------------------------------------------------------------
36 * This rountine will verify that the node being opened as a directory is
37 * in fact a directory node. If it is then the offset into the directory
38 * will be set to 0 to position to the first directory entry.
39 */
40
41int imfs_dir_open(
42  rtems_libio_t  *iop,
43  const char *pathname,
44  unsigned32 flag,
45  unsigned32 mode
46)
47{
48  IMFS_jnode_t      *the_jnode;
49
50  /* Is the node a directory ? */
51  the_jnode = (IMFS_jnode_t *) iop->file_info;
52
53  if ( the_jnode->type != IMFS_DIRECTORY )
54     return -1;         /* It wasn't a directory --> return error */
55
56  iop->offset = 0;
57  return 0;
58}
59
60
61
62/* -----------------------------------------------------------------------
63 * This routine will read the next directory entry based on the directory
64 * offset. The offset should be equal to -n- time the size of an individual
65 * dirent structure. If n is not an integer multiple of the sizeof a
66 * dirent structure, an integer division will be performed to determine
67 * directory entry that will be returned in the buffer. Count should reflect
68 * -m- times the sizeof dirent bytes to be placed in the buffer.
69 * If there are not -m- dirent elements from the current directory position
70 * to the end of the exisiting file, the remaining entries will be placed in
71 * the buffer and the returned value will be equal to -m actual- times the
72 * size of a directory entry.
73 */
74
75int imfs_dir_read(
76  rtems_libio_t  *iop,
77  void *buffer,
78  unsigned32 count
79)
80{
81  /*
82   *  Read up to element  iop->offset in the directory chain of the
83   *  imfs_jnode_t struct for this file descriptor.
84   */
85   Chain_Node        *the_node;
86   Chain_Control     *the_chain;
87   IMFS_jnode_t      *the_jnode;
88   int                bytes_transferred;
89   int                current_entry;
90   int                first_entry;
91   int                last_entry;
92   struct dirent      tmp_dirent;
93
94   the_jnode = (IMFS_jnode_t *)iop->file_info;
95   the_chain = &the_jnode->info.directory.Entries;
96   
97   if ( Chain_Is_empty( the_chain ) )
98      return 0;
99
100   /* Move to the first of the desired directory entries */
101   the_node = the_chain->first;
102
103   bytes_transferred = 0;
104   first_entry = iop->offset;
105   /* protect against using sizes that are not exact multiples of the */
106   /* -dirent- size. These could result in unexpected results          */
107   last_entry = first_entry + (count/sizeof(struct dirent)) * sizeof(struct dirent);
108
109   /* The directory was not empty so try to move to the desired entry in chain*/
110   for(
111      current_entry = 0;
112      current_entry < last_entry;
113      current_entry = current_entry + sizeof(struct dirent) ){
114
115      if ( Chain_Is_tail( the_chain, the_node ) ){
116         /* We hit the tail of the chain while trying to move to the first */
117         /* entry in the read */
118         return bytes_transferred;  /* Indicate that there are no more */
119                                    /* entries to return */
120      }
121   
122      if( current_entry >= first_entry ) {
123         /* Move the entry to the return buffer */
124         tmp_dirent.d_ino = 1;
125         tmp_dirent.d_off = current_entry;
126         tmp_dirent.d_reclen = sizeof( struct dirent );
127         the_jnode = (IMFS_jnode_t *) the_node;
128         tmp_dirent.d_namlen = strlen( the_jnode->name );
129         strcpy( tmp_dirent.d_name, the_jnode->name );
130         memcpy(
131            buffer + bytes_transferred,
132            (void *)&tmp_dirent,
133            sizeof( struct dirent )
134         );
135         iop->offset = iop->offset + sizeof(struct dirent);
136         bytes_transferred = bytes_transferred + sizeof( struct dirent );
137      }
138
139      the_node = the_node->next;
140   }
141
142   /* Success */
143   return bytes_transferred;
144}
145
146
147
148/* -----------------------------------------------------------------------
149 * This routine will be called by the generic close routine to cleanup any
150 * resources that have been allocated for the management of the file
151 */
152
153int imfs_dir_close(
154  rtems_libio_t  *iop
155)
156{
157  /* The generic close routine handles the deallocation of the file control */
158  /* and associated memory. At present the imfs_dir_close simply      */
159  /* returns a successful completion status                                 */
160 
161  return 0;
162}
163
164
165
166/* -----------------------------------------------------------------------
167 * This routine will behave in one of three ways based on the state of
168 * argument whence. Based on the state of its value the offset argument will
169 * be interpreted using one of the following methods:
170 *
171 *      SEEK_SET - offset is the absolute byte offset from the start of the
172 *                 logical start of the dirent sequence that represents the
173 *                 directory
174 *      SEEK_CUR - offset is used as the relative byte offset from the current
175 *                 directory position index held in the iop structure
176 *      SEEK_END - N/A --> This will cause an assert.
177 */
178
179int imfs_dir_lseek(
180  rtems_libio_t  *iop,
181  off_t           offset,
182  int             whence
183)
184{
185  off_t normal_offset;
186
187  normal_offset = (offset/sizeof(struct dirent)) * sizeof(struct dirent);
188
189
190  switch( whence )
191  {
192     case SEEK_SET:     /* absolute move from the start of the file */
193        iop->offset = normal_offset;
194        break;
195
196     case SEEK_CUR:     /* relative move */
197        iop->offset = iop->offset + normal_offset;
198        break;
199
200     case SEEK_END:     /* Movement past the end of the directory via lseek */
201                        /* is not a permitted operation                     */
202      default:
203        set_errno_and_return_minus_one( EINVAL );
204        break;
205
206  }
207
208  return 0;
209}
210
211
212
213/* -----------------------------------------------------------------------
214 * This routine will obtain the following information concerning the current
215 * directory:
216 *      st_dev          0ll
217 *      st_ino          1
218 *      st_mode         mode extracted from the jnode
219 *      st_nlink        number of links to this node
220 *      st_uid          uid extracted from the jnode
221 *      st_gid          gid extracted from the jnode
222 *      st_rdev         0ll
223 *      st_size         the number of bytes in the directory
224 *                      This is calculated by taking the number of entries
225 *                      in the directory and multiplying by the size of a
226 *                      dirent structure
227 *      st_blksize      0
228 *      st_blocks       0
229 *      st_atime        time of last access
230 *      st_mtime        time of last modification
231 *      st_ctime        time of the last change
232 *
233 * This information will be returned to the calling function in a -stat- struct
234 *     
235 */
236
237int imfs_dir_fstat(
238  rtems_filesystem_location_info_t *loc,
239  struct stat                      *buf
240)
241{
242   Chain_Node        *the_node;
243   Chain_Control     *the_chain;
244   IMFS_jnode_t      *the_jnode;
245
246
247   the_jnode = (IMFS_jnode_t *) loc->node_access;
248
249   buf->st_dev = 0ll;
250   buf->st_ino   = the_jnode->st_ino;
251   buf->st_mode  = the_jnode->st_mode;
252   buf->st_nlink = the_jnode->st_nlink;
253   buf->st_uid   = the_jnode->st_uid;
254   buf->st_gid   = the_jnode->st_gid;
255   buf->st_rdev = 0ll;
256   buf->st_blksize = 0;
257   buf->st_blocks = 0;
258   buf->st_atime = the_jnode->st_atime;
259   buf->st_mtime = the_jnode->st_mtime;
260   buf->st_ctime = the_jnode->st_ctime;
261
262   buf->st_size = 0;
263
264   the_chain = &the_jnode->info.directory.Entries;
265
266   /* Run through the chain and count the number of directory entries */
267   /* that are subordinate to this directory node                     */
268   for ( the_node = the_chain->first ;
269         !_Chain_Is_tail( the_chain, the_node ) ;
270         the_node = the_node->next ) {
271 
272      buf->st_size = buf->st_size + sizeof( struct dirent );
273   }
274
275   return 0;
276}
277
278
Note: See TracBrowser for help on using the repository browser.