Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:18

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup rtems_rfs
0007  *
0008  * @brief RTEMS RFS Directory Access Routines
0009  */
0010 /*
0011  *  COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
0012  *
0013  * Redistribution and use in source and binary forms, with or without
0014  * modification, are permitted provided that the following conditions
0015  * are met:
0016  * 1. Redistributions of source code must retain the above copyright
0017  *    notice, this list of conditions and the following disclaimer.
0018  * 2. Redistributions in binary form must reproduce the above copyright
0019  *    notice, this list of conditions and the following disclaimer in the
0020  *    documentation and/or other materials provided with the distribution.
0021  *
0022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0025  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0032  * POSSIBILITY OF SUCH DAMAGE.
0033  */
0034 
0035 #ifdef HAVE_CONFIG_H
0036 #include "config.h"
0037 #endif
0038 
0039 #include <inttypes.h>
0040 
0041 #include <sys/types.h>
0042 #include <sys/stat.h>
0043 #include <fcntl.h>
0044 #include <stdlib.h>
0045 #include <stdio.h>
0046 #include <unistd.h>
0047 
0048 #include <rtems/rfs/rtems-rfs-dir.h>
0049 #include <rtems/rfs/rtems-rfs-link.h>
0050 #include "rtems-rfs-rtems.h"
0051 
0052 /**
0053  * This rountine will verify that the node being opened as a directory is in
0054  * fact a directory node. If it is then the offset into the directory will be
0055  * set to 0 to position to the first directory entry.
0056  */
0057 static int
0058 rtems_rfs_rtems_dir_open (rtems_libio_t* iop,
0059                           const char*    pathname,
0060                           int            oflag,
0061                           mode_t         mode)
0062 {
0063   rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo);
0064   rtems_rfs_ino          ino = rtems_rfs_rtems_get_iop_ino (iop);
0065   rtems_rfs_inode_handle inode;
0066   int                    rc;
0067 
0068   rtems_rfs_rtems_lock (fs);
0069 
0070   rc = rtems_rfs_inode_open (fs, ino, &inode, true);
0071   if (rc)
0072   {
0073     rtems_rfs_rtems_unlock (fs);
0074     return rtems_rfs_rtems_error ("dir_open: opening inode", rc);
0075   }
0076 
0077   if (!RTEMS_RFS_S_ISDIR (rtems_rfs_inode_get_mode (&inode)))
0078   {
0079     rtems_rfs_inode_close (fs, &inode);
0080     rtems_rfs_rtems_unlock (fs);
0081     return rtems_rfs_rtems_error ("dir_open: not dir", ENOTDIR);
0082   }
0083 
0084   iop->offset = 0;
0085 
0086   rtems_rfs_inode_close (fs, &inode);
0087   rtems_rfs_rtems_unlock (fs);
0088   return 0;
0089 }
0090 
0091 /**
0092  * This routine will be called by the generic close routine to cleanup any
0093  * resources that have been allocated for the management of the file
0094  *
0095  * @param iop
0096  * @retval 0 Always no error.
0097  */
0098 static int
0099 rtems_rfs_rtems_dir_close (rtems_libio_t* iop)
0100 {
0101   /*
0102    * The RFS does not hold any resources. Nothing to do.
0103    */
0104   return 0;
0105 }
0106 
0107 /**
0108  * This routine will read the next directory entry based on the directory
0109  * offset. The offset should be equal to -n- time the size of an individual
0110  * dirent structure. If n is not an integer multiple of the sizeof a dirent
0111  * structure, an integer division will be performed to determine directory
0112  * entry that will be returned in the buffer. Count should reflect -m- times
0113  * the sizeof dirent bytes to be placed in the buffer.  If there are not -m-
0114  * dirent elements from the current directory position to the end of the
0115  * exisiting file, the remaining entries will be placed in the buffer and the
0116  * returned value will be equal to -m actual- times the size of a directory
0117  * entry.
0118  */
0119 static ssize_t
0120 rtems_rfs_rtems_dir_read (rtems_libio_t* iop,
0121                           void*          buffer,
0122                           size_t         count)
0123 {
0124   rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo);
0125   rtems_rfs_ino          ino = rtems_rfs_rtems_get_iop_ino (iop);
0126   rtems_rfs_inode_handle inode;
0127   struct dirent*         dirent;
0128   ssize_t                bytes_transferred;
0129   int                    d;
0130   int                    rc;
0131 
0132   count  = count / sizeof (struct dirent);
0133   dirent = buffer;
0134 
0135   rtems_rfs_rtems_lock (fs);
0136 
0137   rc = rtems_rfs_inode_open (fs, ino, &inode, true);
0138   if (rc)
0139   {
0140     rtems_rfs_rtems_unlock (fs);
0141     return rtems_rfs_rtems_error ("dir_read: read inode", rc);
0142   }
0143 
0144   bytes_transferred = 0;
0145 
0146   for (d = 0; d < count; d++, dirent++)
0147   {
0148     size_t size;
0149     rc = rtems_rfs_dir_read (fs, &inode, iop->offset, dirent, &size);
0150     if (rc == ENOENT)
0151     {
0152       rc = 0;
0153       break;
0154     }
0155     if (rc > 0)
0156     {
0157       bytes_transferred = rtems_rfs_rtems_error ("dir_read: dir read", rc);
0158       break;
0159     }
0160     iop->offset += size;
0161     bytes_transferred += sizeof (struct dirent);
0162   }
0163 
0164   rtems_rfs_inode_close (fs, &inode);
0165   rtems_rfs_rtems_unlock (fs);
0166 
0167   return bytes_transferred;
0168 }
0169 
0170 /*
0171  *  Set of operations handlers for operations on directories.
0172  */
0173 
0174 const rtems_filesystem_file_handlers_r rtems_rfs_rtems_dir_handlers = {
0175   .open_h      = rtems_rfs_rtems_dir_open,
0176   .close_h     = rtems_rfs_rtems_dir_close,
0177   .read_h      = rtems_rfs_rtems_dir_read,
0178   .write_h     = rtems_filesystem_default_write,
0179   .ioctl_h     = rtems_filesystem_default_ioctl,
0180   .lseek_h     = rtems_filesystem_default_lseek_directory,
0181   .fstat_h     = rtems_rfs_rtems_fstat,
0182   .ftruncate_h = rtems_filesystem_default_ftruncate_directory,
0183   .fsync_h     = rtems_filesystem_default_fsync_or_fdatasync,
0184   .fdatasync_h = rtems_rfs_rtems_fdatasync,
0185   .fcntl_h     = rtems_filesystem_default_fcntl,
0186   .kqfilter_h  = rtems_filesystem_default_kqfilter,
0187   .mmap_h      = rtems_filesystem_default_mmap,
0188   .poll_h      = rtems_filesystem_default_poll,
0189   .readv_h     = rtems_filesystem_default_readv,
0190   .writev_h    = rtems_filesystem_default_writev
0191 };