/** * This rountine will verify that the node being opened as a directory is in * fact a directory node. If it is then the offset into the directory will be * set to 0 to position to the first directory entry. */ static int rtems_rfs_rtems_dir_open (rtems_libio_t* iop, const char* pathname, int oflag, mode_t mode) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo); rtems_rfs_ino ino = rtems_rfs_rtems_get_iop_ino (iop); rtems_rfs_inode_handle inode; int rc; rtems_rfs_rtems_lock (fs); rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc) { rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("dir_open: opening inode", rc); } if (!RTEMS_RFS_S_ISDIR (rtems_rfs_inode_get_mode (&inode))) { rtems_rfs_inode_close (fs, &inode); rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("dir_open: not dir", ENOTDIR); } iop->offset = 0; rtems_rfs_inode_close (fs, &inode); rtems_rfs_rtems_unlock (fs); return 0; }
/** * This routine will read the next directory entry based on the directory * offset. The offset should be equal to -n- time the size of an individual * dirent structure. If n is not an integer multiple of the sizeof a dirent * structure, an integer division will be performed to determine directory * entry that will be returned in the buffer. Count should reflect -m- times * the sizeof dirent bytes to be placed in the buffer. If there are not -m- * dirent elements from the current directory position to the end of the * exisiting file, the remaining entries will be placed in the buffer and the * returned value will be equal to -m actual- times the size of a directory * entry. */ static ssize_t rtems_rfs_rtems_dir_read (rtems_libio_t* iop, void* buffer, size_t count) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo); rtems_rfs_ino ino = rtems_rfs_rtems_get_iop_ino (iop); rtems_rfs_inode_handle inode; struct dirent* dirent; ssize_t bytes_transferred; int d; int rc; count = count / sizeof (struct dirent); dirent = buffer; rtems_rfs_rtems_lock (fs); rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc) { rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("dir_read: read inode", rc); } bytes_transferred = 0; for (d = 0; d < count; d++, dirent++) { size_t size; rc = rtems_rfs_dir_read (fs, &inode, iop->offset, dirent, &size); if (rc == ENOENT) { rc = 0; break; } if (rc > 0) { bytes_transferred = rtems_rfs_rtems_error ("dir_read: dir read", rc); break; } iop->offset += size; bytes_transferred += sizeof (struct dirent); } rtems_rfs_inode_close (fs, &inode); rtems_rfs_rtems_unlock (fs); return bytes_transferred; }
/** * This handler maps an open() operation onto rtems_io_open(). * * @param iop * @param pathname * @param flag * @param mode * @return int */ static int rtems_rfs_rtems_device_open ( rtems_libio_t *iop, const char *pathname, uint32_t flag, uint32_t mode) { rtems_libio_open_close_args_t args; rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo); rtems_rfs_ino ino = rtems_rfs_rtems_get_iop_ino (iop); rtems_rfs_inode_handle inode; int major; int minor; rtems_status_code status; int rc; rtems_rfs_rtems_lock (fs); rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc > 0) { rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("device_open: opening inode", rc); } major = rtems_rfs_inode_get_block (&inode, 0); minor = rtems_rfs_inode_get_block (&inode, 1); rc = rtems_rfs_inode_close (fs, &inode); if (rc > 0) { rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("device_open: closing inode", rc); } rtems_rfs_rtems_unlock (fs); iop->data0 = major; iop->data1 = (void*)((intptr_t) minor); args.iop = iop; args.flags = iop->flags; args.mode = mode; status = rtems_io_open (major, minor, (void *) &args); if (status) return rtems_deviceio_errno(status); return 0; }
/** * This handler maps an open() operation onto rtems_io_open(). * * @param iop * @param pathname * @param flag * @param mode * @return int */ static int rtems_rfs_rtems_device_open ( rtems_libio_t *iop, const char *pathname, int oflag, mode_t mode) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo); rtems_rfs_ino ino = rtems_rfs_rtems_get_iop_ino (iop); rtems_rfs_inode_handle inode; rtems_device_major_number major; rtems_device_minor_number minor; int rc; rtems_rfs_rtems_lock (fs); rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc > 0) { rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("device_open: opening inode", rc); } major = rtems_rfs_inode_get_block (&inode, 0); minor = rtems_rfs_inode_get_block (&inode, 1); rc = rtems_rfs_inode_close (fs, &inode); if (rc > 0) { rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("device_open: closing inode", rc); } rtems_rfs_rtems_unlock (fs); iop->data0 = major; iop->data1 = (void *) (uintptr_t) minor; return rtems_deviceio_open (iop, pathname, oflag, mode, minor, major); }
static int rtems_rfs_rtems_file_open (rtems_libio_t* iop, const char* pathname, int oflag, mode_t mode) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo); rtems_rfs_ino ino; rtems_rfs_file_handle* file; int flags; int rc; flags = 0; if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_OPEN)) printf("rtems-rfs: file-open: path:%s ino:%" PRId32 " flags:%04i mode:%04" PRIu32 "\n", pathname, ino, flags, mode); rtems_rfs_rtems_lock (fs); ino = rtems_rfs_rtems_get_iop_ino (iop); rc = rtems_rfs_file_open (fs, ino, flags, &file); if (rc > 0) { rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("file-open: open", rc); } if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_OPEN)) printf("rtems-rfs: file-open: handle:%p\n", file); iop->size = rtems_rfs_file_size (file); rtems_rfs_rtems_set_iop_file_handle (iop, file); rtems_rfs_rtems_unlock (fs); return 0; }