diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-05-26 22:37:57 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-05-26 22:37:57 +0000 |
commit | 824fcd39cf4947527eafcbfa7c0dcbc4704b4cb3 (patch) | |
tree | 9958b54a89de6282576ddb77bb4192a079ddb316 /nuttx | |
parent | 503ba396598ab1d5ce6f336cd3543d32d6aacbaa (diff) | |
download | px4-nuttx-824fcd39cf4947527eafcbfa7c0dcbc4704b4cb3.tar.gz px4-nuttx-824fcd39cf4947527eafcbfa7c0dcbc4704b4cb3.tar.bz2 px4-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
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/examples/mount/mount_main.c | 55 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_main.c | 14 | ||||
-rw-r--r-- | nuttx/fs/fs_fat32.c | 2 | ||||
-rw-r--r-- | nuttx/fs/fs_internal.h | 22 | ||||
-rw-r--r-- | nuttx/fs/fs_opendir.c | 174 | ||||
-rw-r--r-- | nuttx/fs/fs_readdir.c | 28 | ||||
-rw-r--r-- | nuttx/include/dirent.h | 6 | ||||
-rw-r--r-- | nuttx/sched/pthread_completejoin.c | 2 |
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 */ |