summaryrefslogtreecommitdiffstats
path: root/nuttx/fs/fs_readdir.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2007-05-26 19:22:34 +0000
committerpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2007-05-26 19:22:34 +0000
commit587cdd45a11652674bbc41147ba8d13215a1dad8 (patch)
tree1deba65ce2f157d8f25da5498676e306742887e8 /nuttx/fs/fs_readdir.c
parentfa9916cac27b36547c6b3b02a368a6a390256fbb (diff)
Finish FAT directory operations; add option to disable mountpoints; fix ARM compile errors
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@252 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'nuttx/fs/fs_readdir.c')
-rw-r--r--nuttx/fs/fs_readdir.c90
1 files changed, 65 insertions, 25 deletions
diff --git a/nuttx/fs/fs_readdir.c b/nuttx/fs/fs_readdir.c
index 4c2d792272..6cb3eb0992 100644
--- a/nuttx/fs/fs_readdir.c
+++ b/nuttx/fs/fs_readdir.c
@@ -53,52 +53,59 @@
* Name: readpsuedodir
************************************************************/
-static inline FAR struct dirent *readpsuedodir(struct internal_dir_s *idir)
+#if CONFIG_NFILE_DESCRIPTORS > 0
+
+static inline int readpsuedodir(struct internal_dir_s *idir)
{
FAR struct inode *prev;
/* Check if we are at the end of the list */
- if (!idir->u.psuedo.next)
+ if (!idir->u.psuedo.fd_next)
{
- return NULL;
+ /* End of file and error conditions are not distinguishable
+ * with readdir. Here we return -ENOENT to signal the end
+ * of the directory.
+ */
+
+ return -ENOENT;
}
/* Copy the inode name into the dirent structure */
- strncpy(idir->dir.d_name, idir->u.psuedo.next->i_name, NAME_MAX+1);
+ strncpy(idir->fd_dir.d_name, idir->u.psuedo.fd_next->i_name, NAME_MAX+1);
/* If the node has file operations, we will say that it is
* a file.
*/
- idir->dir.d_type = 0;
- if (idir->u.psuedo.next->u.i_ops)
+ idir->fd_dir.d_type = 0;
+ if (idir->u.psuedo.fd_next->u.i_ops)
{
- idir->dir.d_type |= DTYPE_FILE;
+ idir->fd_dir.d_type |= DTYPE_FILE;
}
/* If the node has child node(s), then we will say that it
* is a directory. NOTE: that the node can be both!
*/
- if (idir->u.psuedo.next->i_child || !idir->u.psuedo.next->u.i_ops)
+ if (idir->u.psuedo.fd_next->i_child || !idir->u.psuedo.fd_next->u.i_ops)
{
- idir->dir.d_type |= DTYPE_DIRECTORY;
+ idir->fd_dir.d_type |= DTYPE_DIRECTORY;
}
/* Now get the inode to vist next time that readdir() is called */
inode_semtake();
- prev = idir->u.psuedo.next;
- idir->u.psuedo.next = prev->i_peer; /* The next node to visit */
+ prev = idir->u.psuedo.fd_next;
+ idir->u.psuedo.fd_next = prev->i_peer; /* The next node to visit */
- if (idir->u.psuedo.next)
+ if (idir->u.psuedo.fd_next)
{
/* Increment the reference count on this next node */
- idir->u.psuedo.next->i_crefs++;
+ idir->u.psuedo.fd_next->i_crefs++;
}
inode_semgive();
@@ -108,7 +115,7 @@ static inline FAR struct dirent *readpsuedodir(struct internal_dir_s *idir)
inode_release(prev);
}
- return &idir->dir;
+ return OK;
}
/************************************************************
@@ -137,39 +144,72 @@ static inline FAR struct dirent *readpsuedodir(struct internal_dir_s *idir)
*
************************************************************/
-#if CONFIG_NFILE_DESCRIPTORS > 0
-
FAR struct dirent *readdir(DIR *dirp)
{
FAR struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
+ struct inode *inode;
+ int ret;
/* Sanity checks */
- if (!idir || !idir->root)
+ if (!idir || !idir->fd_root)
{
- *get_errno_ptr() = EBADF;
- return NULL;
+ ret = EBADF;
+ goto errout;
}
/* The way we handle the readdir depends on the type of inode
* that we are dealing with.
*/
- if (INODE_IS_MOUNTPT(idir->root))
+ inode = idir->fd_root;
+ if (INODE_IS_MOUNTPT(inode))
{
- /* The node is a file system mointpoint */
+ /* The node is a file system mointpoint. Verify that the mountpoint
+ * supports the readdir() method
+ */
+
+ if (!inode->u.i_mops || !inode->u.i_mops->readdir)
+ {
+ ret = EACCES;
+ goto errout;
+ }
-#warning "Mountpoint support not implemented"
- *get_errno_ptr() = ENOSYS;
- return NULL;
+ /* Perform the readdir() operation */
+
+ ret = inode->u.i_mops->readdir(inode, idir);
}
else
{
/* The node is part of the root psuedo file system, release
* our contained reference to the 'next' inode.
*/
- return readpsuedodir(idir);
+ ret = readpsuedodir(idir);
+ }
+
+ /* ret < 0 is an error. Special case: ret = -ENOENT is end of file */
+
+ if ( ret < 0)
+ {
+ if (ret == -ENOENT)
+ {
+ ret = OK;
+ }
+ else
+ {
+ ret = -ret;
+ }
+ goto errout;
}
+
+ /* Success */
+
+ idir->fd_position++;
+ return &idir->fd_dir;
+
+errout:
+ *get_errno_ptr() = ret;
+ return NULL;
}
#endif /* CONFIG_NFILE_DESCRIPTORS */