summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-26 22:37:57 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-26 22:37:57 +0000
commit824fcd39cf4947527eafcbfa7c0dcbc4704b4cb3 (patch)
tree9958b54a89de6282576ddb77bb4192a079ddb316
parent503ba396598ab1d5ce6f336cd3543d32d6aacbaa (diff)
downloadnuttx-824fcd39cf4947527eafcbfa7c0dcbc4704b4cb3.tar.gz
nuttx-824fcd39cf4947527eafcbfa7c0dcbc4704b4cb3.tar.bz2
nuttx-824fcd39cf4947527eafcbfa7c0dcbc4704b4cb3.zip
Fat dir operations seem to work
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@254 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/examples/mount/mount_main.c55
-rw-r--r--nuttx/examples/nsh/nsh_main.c14
-rw-r--r--nuttx/fs/fs_fat32.c2
-rw-r--r--nuttx/fs/fs_internal.h22
-rw-r--r--nuttx/fs/fs_opendir.c174
-rw-r--r--nuttx/fs/fs_readdir.c28
-rw-r--r--nuttx/include/dirent.h6
-rw-r--r--nuttx/sched/pthread_completejoin.c2
8 files changed, 189 insertions, 114 deletions
diff --git a/nuttx/examples/mount/mount_main.c b/nuttx/examples/mount/mount_main.c
index 0656951d7..a3c75d2ae 100644
--- a/nuttx/examples/mount/mount_main.c
+++ b/nuttx/examples/mount/mount_main.c
@@ -46,6 +46,7 @@
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
+#include <dirent.h>
#include <errno.h>
/****************************************************************************
@@ -76,6 +77,8 @@ static const char g_testmsg[] = "This is a write test";
static int g_nerrors = 0;
+static char g_namebuffer[256];
+
/****************************************************************************
* Private Functions
****************************************************************************/
@@ -84,6 +87,48 @@ static int g_nerrors = 0;
* Name: fail_read_open
****************************************************************************/
+static void show_directories( const char *path, int indent )
+{
+ DIR *dirp;
+ struct dirent *direntry;
+ int i;
+
+ dirp = opendir(path);
+ if ( !dirp )
+ {
+ printf("show_directories: ERROR opendir(\"%s\") failed with errno=%d\n", path, *get_errno_ptr());
+ g_nerrors++;
+ return;
+ }
+
+ for (direntry = readdir(dirp); direntry; direntry = readdir(dirp))
+ {
+ for (i = 0; i < 2*indent; i++)
+ {
+ putchar(' ');
+ }
+ if (DIRENT_ISDIRECTORY(direntry->d_type))
+ {
+ char *subdir;
+ printf("%s/\n", direntry->d_name);
+ sprintf(g_namebuffer, "%s/%s", path, direntry->d_name);
+ subdir = strdup(g_namebuffer);
+ show_directories( subdir, indent + 1);
+ free(subdir);
+ }
+ else
+ {
+ printf("%s\n", direntry->d_name);
+ }
+ }
+
+ closedir(dirp);
+}
+
+/****************************************************************************
+ * Name: fail_read_open
+ ****************************************************************************/
+
static void fail_read_open(const char *path, int expectederror)
{
int fd;
@@ -396,11 +441,13 @@ int user_start(int argc, char *argv[])
{
/* Read a test file that is already on the test file system image */
+ show_directories("", 0);
read_test_file(g_testfile1);
/* Write a test file into a pre-existing directory on the test file system */
write_test_file(g_testfile2);
+ show_directories("", 0);
/* Read the file that we just wrote */
@@ -421,6 +468,7 @@ int user_start(int argc, char *argv[])
/* Try unlink() against the test file1. It should succeed. */
succeed_unlink(g_testfile1);
+ show_directories("", 0);
/* Attempt to open testfile1 should fail with ENOENT */
@@ -437,6 +485,7 @@ int user_start(int argc, char *argv[])
/* Try unlink() against the test file2. It should succeed. */
succeed_unlink(g_testfile2);
+ show_directories("", 0);
/* Try mkdir() against the test dir1. It should fail with EEXIST. */
@@ -445,10 +494,12 @@ int user_start(int argc, char *argv[])
/* Try rmdir() against the test directory. It should now succeed. */
succeed_rmdir(g_testdir1);
+ show_directories("", 0);
/* Try mkdir() against the test dir2. It should succeed */
succeed_mkdir(g_testdir2);
+ show_directories("", 0);
/* Try mkdir() against the test dir2. It should fail with EXIST */
@@ -457,6 +508,7 @@ int user_start(int argc, char *argv[])
/* Write a test file into a new directory on the test file system */
write_test_file(g_testfile3);
+ show_directories("", 0);
/* Read the file that we just wrote */
@@ -465,6 +517,7 @@ int user_start(int argc, char *argv[])
/* Use mkdir() to create test dir3. It should succeed */
succeed_mkdir(g_testdir3);
+ show_directories("", 0);
/* Try rename() on the root directory. Should fail with EXDEV*/
@@ -477,10 +530,12 @@ int user_start(int argc, char *argv[])
/* Try rename() to a non-existing directory. Should succeed */
succeed_rename(g_testdir3, g_testdir4);
+ show_directories("", 0);
/* Try rename() of file. Should work. */
succeed_rename(g_testfile3, g_testfile4);
+ show_directories("", 0);
/* Make sure that we can still read the renamed file */
diff --git a/nuttx/examples/nsh/nsh_main.c b/nuttx/examples/nsh/nsh_main.c
index e9c8466c3..951742e2a 100644
--- a/nuttx/examples/nsh/nsh_main.c
+++ b/nuttx/examples/nsh/nsh_main.c
@@ -254,23 +254,23 @@ static void cmd_ls(const char *cmd, char *arg)
break;
}
- if (DIRENT_ISFILE(entryp->d_type))
+ if (DIRENT_ISDIRECTORY(entryp->d_type))
{
#ifdef CONFIG_FULL_PATH
- printf(" %s/%s\n", arg, entryp->d_name);
+ printf(" %s/%s/\n", arg, entryp->d_name);
#else
- printf(" %s\n", entryp->d_name);
+ printf(" %s/\n", entryp->d_name);
#endif
}
-
- if (DIRENT_ISDIRECTORY(entryp->d_type))
+ else
{
#ifdef CONFIG_FULL_PATH
- printf(" %s/%s/\n", arg, entryp->d_name);
+ printf(" %s/%s\n", arg, entryp->d_name);
#else
- printf(" %s/\n", entryp->d_name);
+ printf(" %s\n", entryp->d_name);
#endif
}
+
}
closedir(dirp);
}
diff --git a/nuttx/fs/fs_fat32.c b/nuttx/fs/fs_fat32.c
index adb6c47b6..633695fd1 100644
--- a/nuttx/fs/fs_fat32.c
+++ b/nuttx/fs/fs_fat32.c
@@ -1262,7 +1262,7 @@ static int fat_opendir(struct inode *mountpt, const char *relpath, struct intern
/* This is not the root directory. Verify that it is some kind of directory */
- else if (DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_DIRECTORY)
+ else if ((DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_DIRECTORY) == 0)
{
/* The entry is not a directory */
ret = -ENOTDIR;
diff --git a/nuttx/fs/fs_internal.h b/nuttx/fs/fs_internal.h
index 432344515..8bfc52f21 100644
--- a/nuttx/fs/fs_internal.h
+++ b/nuttx/fs/fs_internal.h
@@ -69,6 +69,13 @@
#define INODE_SET_MOUNTPT(i) \
((i)->i_flags = (((i)->i_flags & ~FSNODEFLAG_TYPE_MASK) | FSNODEFLAG_TYPE_MOUNTPT))
+/* Mountpoint fd_flags values */
+
+#define DIRENTFLAGS_PSUEDONODE 1
+
+#define DIRENT_SETPSUEDONODE(f) do (f) |= DIRENTFLAGS_PSUEDONODE; while (0)
+#define DIRENT_ISPSUEDONODE(f) (((f) & DIRENTFLAGS_PSUEDONODE) != 0)
+
/****************************************************************************
* Public Types
****************************************************************************/
@@ -87,7 +94,7 @@ struct fs_psuedodir_s
struct inode *fd_next; /* The inode for the next call to readdir() */
};
-#ifdef CONFIG_FS_FAT
+#if defined(CONFIG_FS_FAT) && !defined(CONFIG_DISABLE_MOUNTPOINT)
/* For fat, we need to retun the start cluster, current cluster, current
* sector and current directory index.
*/
@@ -113,6 +120,12 @@ struct internal_dir_s
struct inode *fd_root;
+ /* At present, only mountpoints require special handling flags */
+
+#ifndef CONFIG_DISABLE_MOUNTPOINT
+ unsigned int fd_flags;
+#endif
+
/* This keeps track of the current directory position for telldir */
off_t fd_position;
@@ -125,10 +138,17 @@ struct internal_dir_s
union
{
+ /* Private data used by the built-in psuedo-file system */
+
struct fs_psuedodir_s psuedo;
+
+ /* Private data used by other file systems */
+
+#ifndef CONFIG_DISABLE_MOUNTPOINT
#ifdef CONFIG_FS_FAT
struct fs_fatdir_s fat;
#endif
+#endif
} u;
/* In any event, this the actual struct dirent that is returned by readdir */
diff --git a/nuttx/fs/fs_opendir.c b/nuttx/fs/fs_opendir.c
index 6791195a2..58a1f4bb2 100644
--- a/nuttx/fs/fs_opendir.c
+++ b/nuttx/fs/fs_opendir.c
@@ -51,81 +51,6 @@
************************************************************/
/************************************************************
- * Name: fs_finddirnode
- *
- * Description:
- * This is called from the opendir() logic to get a reference
- * to the inode associated with a directory. There are no
- * real directories in this design; For our purposes, a
- * directory inode is simply one that has children or one
- * that is a mountpoint for a "real" file system
- *
- ************************************************************/
-
-static inline FAR struct inode *fs_finddirnode(const char *path, const char **relpath)
-{
- FAR struct inode *node;
- FAR struct inode *root = NULL;
-
- /* If we are given 'nothing' then we will interpret this as
- * request for the root inode.
- */
-
- if (!path || *path == 0 || strcmp(path, "/") == 0)
- {
- return root_inode;
- }
-
- /* We don't know what to do with relative pathes */
-
- if (*path != '/')
- {
- return NULL;
- }
-
- /* Find the node matching the path. */
-
- inode_semtake();
- node = inode_search(&path, (FAR void*)NULL, (FAR void*)NULL, relpath);
- if (node)
- {
-
- /* Is this a not in the psuedo filesystem? */
-
- if (INODE_IS_MOUNTPT(node))
- {
- /* Yes, then return the inode itself as the 'root' of
- * the directory. The actually directory is at relpath into the
- * mounted filesystem. Increment the count of references
- * on the inode.
- */
-
- root = node;
- root->i_crefs++;
- }
- else
- {
- /* It is a node in the psuedo filesystem. Does the inode have a child?
- * If so that the child would be the 'root' of a list of nodes under
- * the directory.
- */
-
- root = node->i_child;
- if (root)
- {
- /* If found, then increment the count of
- * references on the child node.
- */
-
- root->i_crefs++;
- }
- }
- }
- inode_semgive();
- return root;
-}
-
-/************************************************************
* Public Functions
************************************************************/
@@ -161,22 +86,45 @@ static inline FAR struct inode *fs_finddirnode(const char *path, const char **re
FAR DIR *opendir(const char *path)
{
- FAR struct inode *inode;
+ FAR struct inode *inode = NULL;
FAR struct internal_dir_s *dir;
const char *relpath;
+ boolean isroot = FALSE;
int ret;
- /* Get an inode corresponding to the path. On successful
- * return, we will hold on reference count on the inode.
+ /* If we are given 'nothing' then we will interpret this as
+ * request for the root inode.
*/
- inode = fs_finddirnode(path, &relpath);
+ if (!path || *path == 0 || strcmp(path, "/") == 0)
+ {
+ inode_semgive();
+ inode = root_inode;
+ isroot = TRUE;
+ }
+ else
+ {
+ /* We don't know what to do with relative pathes */
+
+ if (*path != '/')
+ {
+ return NULL;
+ }
+
+ /* Find the node matching the path. */
+
+ inode_semtake();
+ inode = inode_search(&path, (FAR void*)NULL, (FAR void*)NULL, &relpath);
+ }
+
+ /* Did we get an inode? */
+
if (!inode)
{
- /* 'path' is not a directory.*/
+ /* 'path' is not a does not exist.*/
ret = ENOTDIR;
- goto errout;
+ goto errout_with_semaphore;
}
/* Allocate a type DIR -- which is little more than an inode
@@ -189,7 +137,7 @@ FAR DIR *opendir(const char *path)
/* Insufficient memory to complete the operation.*/
ret = ENOMEM;
- goto errout_with_inode;
+ goto errout_with_semaphore;
}
/* Populate the DIR structure and return it to the caller. The way that
@@ -200,20 +148,29 @@ FAR DIR *opendir(const char *path)
dir->fd_root = inode; /* Save the inode where we start */
dir->fd_position = 0; /* This is the position in the read stream */
- /* Is this a not in the psuedo filesystem? */
+ /* Is this a node in the psuedo filesystem? Or a mountpoint? */
+
+#ifndef CONFIG_DISABLE_MOUNTPOINT
+ if (INODE_IS_MOUNTPT(inode))
+ {
+ /* Yes, then return the inode itself as the 'root' of
+ * the directory. The actually directory is at relpath into the
+ * mounted filesystem.
+ */
-#ifndef CONFIG_DISABLE_MOUNTPOUNT
- if (INODE_IS_MOUNTPT(inode))
- {
/* The node is a file system mointpoint. Verify that the mountpoint
- * supports the opendir() method
- */
+ * supports the opendir() method
+ */
if (!inode->u.i_mops || !inode->u.i_mops->opendir)
- {
+ {
ret = ENOSYS;
goto errout_with_direntry;
- }
+ }
+
+ /* Take reference to the mountpoint inode (fd_root) */
+
+ inode_addref(inode);
/* Perform the opendir() operation */
@@ -221,27 +178,52 @@ FAR DIR *opendir(const char *path)
if (ret < 0)
{
ret = -ret;
- goto errout_with_direntry;
+ goto errout_with_inode;
}
}
else
#endif
{
- /* The node is part of the root psuedo file system */
+ /* The node is part of the root psuedo file system. Does the inode have a child?
+ * If so that the child would be the 'root' of a list of nodes under
+ * the directory.
+ */
+
+ if (!isroot)
+ {
+ inode = inode->i_child;
+ if (!inode)
+ {
+ ret = ENOTDIR;
+ goto errout_with_direntry;
+ }
+ }
- inode_addref(inode); /* Now we have two references on inode */
+ /* It looks we have a valid psuedo-filesystem node. Take two references
+ * on the inode -- one for the parent (fd_root) and one for the child (fd_next).
+ */
+
+ inode_addref(inode);
+ inode_addref(inode);
dir->u.psuedo.fd_next = inode; /* This is the next node to use for readdir() */
+
+ /* Flag the inode as belonging to the psuedo-filesystem */
+#ifndef CONFIG_DISABLE_MOUNTPOINT
+ DIRENT_SETPSUEDONODE(dir->fd_flags);
+#endif
}
+ inode_semgive();
return ((DIR*)dir);
/* Nasty goto's make error handling simpler */
-errout_with_direntry:
- free(dir);
errout_with_inode:
inode_release(inode);
-errout:
+errout_with_direntry:
+ free(dir);
+errout_with_semaphore:
+ inode_semgive();
*get_errno_ptr() = ret;
return NULL;
}
diff --git a/nuttx/fs/fs_readdir.c b/nuttx/fs/fs_readdir.c
index 6cb3eb099..0c15d04e9 100644
--- a/nuttx/fs/fs_readdir.c
+++ b/nuttx/fs/fs_readdir.c
@@ -82,7 +82,20 @@ static inline int readpsuedodir(struct internal_dir_s *idir)
idir->fd_dir.d_type = 0;
if (idir->u.psuedo.fd_next->u.i_ops)
{
- idir->fd_dir.d_type |= DTYPE_FILE;
+#ifndef CONFIG_DISABLE_MOUNTPOINT
+ if (INODE_IS_BLOCK(idir->u.psuedo.fd_next))
+ {
+ idir->fd_dir.d_type |= DTYPE_BLK;
+ }
+ if (INODE_IS_MOUNTPT(idir->u.psuedo.fd_next))
+ {
+ idir->fd_dir.d_type |= DTYPE_DIRECTORY;
+ }
+ else
+#endif
+ {
+ idir->fd_dir.d_type |= DTYPE_CHR;
+ }
}
/* If the node has child node(s), then we will say that it
@@ -147,7 +160,9 @@ static inline int readpsuedodir(struct internal_dir_s *idir)
FAR struct dirent *readdir(DIR *dirp)
{
FAR struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
+#ifndef CONFIG_DISABLE_MOUNTPOINT
struct inode *inode;
+#endif
int ret;
/* Sanity checks */
@@ -162,8 +177,9 @@ FAR struct dirent *readdir(DIR *dirp)
* that we are dealing with.
*/
+#ifndef CONFIG_DISABLE_MOUNTPOINT
inode = idir->fd_root;
- if (INODE_IS_MOUNTPT(inode))
+ if (INODE_IS_MOUNTPT(inode) && !DIRENT_ISPSUEDONODE(idir->fd_flags))
{
/* The node is a file system mointpoint. Verify that the mountpoint
* supports the readdir() method
@@ -172,7 +188,7 @@ FAR struct dirent *readdir(DIR *dirp)
if (!inode->u.i_mops || !inode->u.i_mops->readdir)
{
ret = EACCES;
- goto errout;
+ goto errout;
}
/* Perform the readdir() operation */
@@ -180,10 +196,10 @@ FAR struct dirent *readdir(DIR *dirp)
ret = inode->u.i_mops->readdir(inode, idir);
}
else
+#endif
{
- /* The node is part of the root psuedo file system, release
- * our contained reference to the 'next' inode.
- */
+ /* The node is part of the root psuedo file system */
+
ret = readpsuedodir(idir);
}
diff --git a/nuttx/include/dirent.h b/nuttx/include/dirent.h
index e0d9fca68..e28990cd2 100644
--- a/nuttx/include/dirent.h
+++ b/nuttx/include/dirent.h
@@ -54,9 +54,13 @@
*/
#define DTYPE_FILE 0x01
-#define DTYPE_DIRECTORY 0x02
+#define DTYPE_CHR 0x02
+#define DTYPE_BLK 0x04
+#define DTYPE_DIRECTORY 0x08
#define DIRENT_ISFILE(dtype) (((dtype) & DTYPE_FILE) != 0 )
+#define DIRENT_ISCHR(dtype) (((dtype) & DTYPE_CHR) != 0 )
+#define DIRENT_ISBLK(dtype) (((dtype) & DTYPE_BLK) != 0 )
#define DIRENT_ISDIRECTORY(dtype) (((dtype) & DTYPE_DIRECTORY) != 0 )
/************************************************************
diff --git a/nuttx/sched/pthread_completejoin.c b/nuttx/sched/pthread_completejoin.c
index 76b2e9f80..eb3f4c011 100644
--- a/nuttx/sched/pthread_completejoin.c
+++ b/nuttx/sched/pthread_completejoin.c
@@ -209,8 +209,6 @@ int pthread_completejoin(pid_t pid, FAR void *exit_value)
void pthread_destroyjoin(FAR join_t *pjoin)
{
- int status;
-
dbg("pjoin=0x%p\n", pjoin);
/* Remove the join info from the set of joins */