diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-01-16 14:14:14 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-01-16 14:14:14 +0000 |
commit | 77efc9f9cdd5828ab724b3355f0f0737bb15b579 (patch) | |
tree | 5c82c94b6cb8e68f1ffda9326d9cb2f108e5db86 /apps/builtin/binfs.c | |
parent | fcb316906d1741c28292e94eb7f09bd4d71ccb48 (diff) | |
download | px4-firmware-77efc9f9cdd5828ab724b3355f0f0737bb15b579.tar.gz px4-firmware-77efc9f9cdd5828ab724b3355f0f0737bb15b579.tar.bz2 px4-firmware-77efc9f9cdd5828ab724b3355f0f0737bb15b579.zip |
BINFS now supports open, close, and FIOC_FILENAME ioctl
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5522 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'apps/builtin/binfs.c')
-rw-r--r-- | apps/builtin/binfs.c | 331 |
1 files changed, 73 insertions, 258 deletions
diff --git a/apps/builtin/binfs.c b/apps/builtin/binfs.c index 1fc2e7940..611e2b3bb 100644 --- a/apps/builtin/binfs.c +++ b/apps/builtin/binfs.c @@ -45,7 +45,6 @@ #include <stdint.h> #include <stdbool.h> -#include <stdlib.h> #include <string.h> #include <fcntl.h> #include <assert.h> @@ -53,8 +52,11 @@ #include <debug.h> #include <nuttx/fs/fs.h> +#include <nuttx/fs/binfs.h> #include <nuttx/fs/dirent.h> +#include <apps/apps.h> + #include "builtin.h" #if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_APPS_BINDIR) @@ -63,24 +65,12 @@ * Private Types ****************************************************************************/ -/* This structure represents the overall mountpoint state. An instance of this - * structure is retained as inode private data on each mountpoint that is - * mounted with a fat32 filesystem. - */ - -struct binfs_state_s -{ - sem_t bm_sem; /* Used to assume thread-safe access */ -}; - /**************************************************************************** * Private Function Prototypes ****************************************************************************/ -static void binfs_semtake(struct binfs_state_s *bm); -static inline void binfs_semgive(struct binfs_state_s *bm); static int binfs_open(FAR struct file *filep, const char *relpath, - int oflags, mode_t mode); + int oflags, mode_t mode); static int binfs_close(FAR struct file *filep); static ssize_t binfs_read(FAR struct file *filep, char *buffer, size_t buflen); static int binfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg); @@ -89,15 +79,19 @@ static int binfs_dup(FAR const struct file *oldp, FAR struct file *newp); static int binfs_opendir(struct inode *mountpt, const char *relpath, struct fs_dirent_s *dir); -static int binfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir); -static int binfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir); +static int binfs_readdir(FAR struct inode *mountpt, + FAR struct fs_dirent_s *dir); +static int binfs_rewinddir(FAR struct inode *mountpt, + FAR struct fs_dirent_s *dir); -static int binfs_bind(FAR struct inode *blkdriver, const void *data, - void **handle); -static int binfs_unbind(void *handle, FAR struct inode **blkdriver); -static int binfs_statfs(struct inode *mountpt, struct statfs *buf); +static int binfs_bind(FAR struct inode *blkdriver, FAR const void *data, + FAR void **handle); +static int binfs_unbind(FAR void *handle, FAR struct inode **blkdriver); +static int binfs_statfs(FAR struct inode *mountpt, + FAR struct statfs *buf); -static int binfs_stat(struct inode *mountpt, const char *relpath, struct stat *buf); +static int binfs_stat(FAR struct inode *mountpt, FAR const char *relpath, + FAR struct stat *buf); /**************************************************************************** * Private Variables @@ -145,70 +139,41 @@ const struct mountpt_operations binfs_operations = ****************************************************************************/ /**************************************************************************** - * Name: binfs_semtake - ****************************************************************************/ - -static void binfs_semtake(struct binfs_state_s *bm) -{ - /* Take the semaphore (perhaps waiting) */ - - while (sem_wait(&bm->bm_sem) != 0) - { - /* The only case that an error should occur here is if - * the wait was awakened by a signal. - */ - - ASSERT(errno == EINTR); - } -} - -/**************************************************************************** - * Name: binfs_semgive - ****************************************************************************/ - -static inline void binfs_semgive(struct binfs_state_s *bm) -{ - sem_post(&bm->bm_sem); -} - -/**************************************************************************** * Name: binfs_open ****************************************************************************/ -static int binfs_open(FAR struct file *filep, const char *relpath, - int oflags, mode_t mode) +static int binfs_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode) { - struct binfs_state_s *bm; - int ret = -ENOSYS; + int index; fvdbg("Open '%s'\n", relpath); - /* Sanity checks */ - - DEBUGASSERT(filep->f_priv == NULL && filep->f_inode != NULL); - - /* mountpoint private data from the inode reference from the file - * structure - */ - - bm = (struct binfs_state_s*)filep->f_inode->i_private; - DEBUGASSERT(bm != NULL); - /* BINFS is read-only. Any attempt to open with any kind of write * access is not permitted. */ if ((oflags & O_WRONLY) != 0 || (oflags & O_RDONLY) == 0) { - fdbg("Only O_RDONLY supported\n"); - ret = -EACCES; + fdbg("ERROR: Only O_RDONLY supported\n"); + return -EACCES; } - /* Save open-specific state in filep->f_priv */ + /* Check if the an entry exists with this name in the root directory. + * so the 'relpath' must be the name of the builtin function. + */ - /* Opening of elements within the pseudo-file system is not yet supported */ + index = builtin_isavail(relpath); + if (index < 0) + { + fdbg("ERROR: Builting %s does not exist\n", relpath); + return -ENOENT; + } - return ret; + /* Save the index as the open-specific state in filep->f_priv */ + + filep->f_priv = (FAR void *)index; + return OK; } /**************************************************************************** @@ -217,31 +182,8 @@ static int binfs_open(FAR struct file *filep, const char *relpath, static int binfs_close(FAR struct file *filep) { - struct binfs_state_s *bm; - int ret = -ENOSYS; - fvdbg("Closing\n"); - - /* Sanity checks */ - - DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL); - - /* Recover the open file state from the struct file instance */ - /* bf = filep->f_priv; */ - - /* Recover the file system state from the inode */ - - bm = filep->f_inode->i_private; - DEBUGASSERT(bm != NULL); - - /* Free the open file state */ - /* free(bf); */ - - filep->f_priv = NULL; - - /* Since open() is not yet supported, neither is close(). */ - - return ret; + return OK; } /**************************************************************************** @@ -250,25 +192,10 @@ static int binfs_close(FAR struct file *filep) static ssize_t binfs_read(FAR struct file *filep, char *buffer, size_t buflen) { - struct binfs_state_s *bm; + /* Reading is not supported. Just return end-of-file */ fvdbg("Read %d bytes from offset %d\n", buflen, filep->f_pos); - - /* Sanity checks */ - - DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL); - - /* Recover the open file state data from the struct file instance */ - /* bf = filep->f_priv; */ - - /* Recover the file system state from the inode */ - - bm = filep->f_inode->i_private; - DEBUGASSERT(bm != NULL); - - /* Since open is not yet supported, neither is reading */ - - return -ENOSYS; + return 0; } /**************************************************************************** @@ -277,25 +204,36 @@ static ssize_t binfs_read(FAR struct file *filep, char *buffer, size_t buflen) static int binfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { - struct binfs_state_s *bm; + int ret; fvdbg("cmd: %d arg: %08lx\n", cmd, arg); - /* Sanity checks */ - - DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL); - - /* Recover the open file state from the struct file instance */ - /* bf = filep->f_priv; */ + /* Only one IOCTL command is supported */ - /* Recover the file system state from the inode */ - - bm = filep->f_inode->i_private; - DEBUGASSERT(bm != NULL); + if (cmd == FIOC_FILENAME) + { + /* IN: FAR char const ** pointer + * OUT: Pointer to a persistent file name (Guaranteed to persist while + * the file is open). + */ - /* No ioctl commands yet supported */ + FAR const char **ptr = (FAR const char **)((uintptr_t)arg); + if (ptr == NULL) + { + ret = -EINVAL; + } + else + { + *ptr = g_builtins[(int)filep->f_priv].name; + ret = OK; + } + } + else + { + ret = -ENOTTY; + } - return -ENOTTY; + return ret; } /**************************************************************************** @@ -308,27 +246,12 @@ static int binfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg) static int binfs_dup(FAR const struct file *oldp, FAR struct file *newp) { - struct binfs_state_s *bm; - int ret = -ENOSYS; - fvdbg("Dup %p->%p\n", oldp, newp); - /* Sanity checks */ - - DEBUGASSERT(oldp->f_priv == NULL && oldp->f_inode != NULL); - - /* mountpoint private data from the inode reference from the file - * structure - */ - - bm = (struct binfs_state_s*)oldp->f_inode->i_private; - DEBUGASSERT(bm != NULL); - - /* Opening of elements within the pseudo-file system is not yet supported - * and, hence, neither is dup'ing the opened file. - */ + /* Copy the index from the old to the new file structure */ - return ret; + newp->f_priv = oldp->f_priv; + return OK; } /**************************************************************************** @@ -342,36 +265,19 @@ static int binfs_dup(FAR const struct file *oldp, FAR struct file *newp) static int binfs_opendir(struct inode *mountpt, const char *relpath, struct fs_dirent_s *dir) { - struct binfs_state_s *bm; - int ret; - fvdbg("relpath: \"%s\"\n", relpath ? relpath : "NULL"); - /* Sanity checks */ - - DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL); - - /* Recover the file system state from the inode instance */ - - bm = mountpt->i_private; - binfs_semtake(bm); - /* The requested directory must be the volume-relative "root" directory */ if (relpath && relpath[0] != '\0') { - ret = -ENOENT; - goto errout_with_semaphore; + return -ENOENT; } /* Set the index to the first entry */ dir->u.binfs.fb_index = 0; - ret = OK; - -errout_with_semaphore: - binfs_semgive(bm); - return ret; + return OK; } /**************************************************************************** @@ -383,19 +289,9 @@ errout_with_semaphore: static int binfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) { - struct binfs_state_s *bm; unsigned int index; int ret; - /* Sanity checks */ - - DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL); - - /* Recover the file system state from the inode instance */ - - bm = mountpt->i_private; - binfs_semtake(bm); - /* Have we reached the end of the directory */ index = dir->u.binfs.fb_index; @@ -426,11 +322,10 @@ static int binfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) * standard f_pos instead of our own private fb_index. */ - dir->u.binfs.fb_index = index; - ret = OK; + dir->u.binfs.fb_index = index; + ret = OK; } - binfs_semgive(bm); return ret; } @@ -443,22 +338,9 @@ static int binfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) static int binfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir) { - struct binfs_state_s *bm; - fvdbg("Entry\n"); - /* Sanity checks */ - - DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL); - - /* Recover the file system state from the inode instance */ - - bm = mountpt->i_private; - binfs_semtake(bm); - - dir->u.binfs.fb_index = 0; - - binfs_semgive(bm); + dir->u.binfs.fb_index = 0; return OK; } @@ -476,29 +358,7 @@ static int binfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir) static int binfs_bind(FAR struct inode *blkdriver, const void *data, void **handle) { - struct binfs_state_s *bm; - fvdbg("Entry\n"); - - /* Create an instance of the mountpt state structure */ - - bm = (struct binfs_state_s *)zalloc(sizeof(struct binfs_state_s)); - if (!bm) - { - fdbg("Failed to allocate mountpoint structure\n"); - return -ENOMEM; - } - - /* Initialize the allocated mountpt state structure. The filesystem is - * responsible for one reference ont the blkdriver inode and does not - * have to addref() here (but does have to release in ubind(). - */ - - sem_init(&bm->bm_sem, 0, 1); /* Initialize the semaphore that controls access */ - - /* Mounted! */ - - *handle = (void*)bm; return OK; } @@ -512,22 +372,7 @@ static int binfs_bind(FAR struct inode *blkdriver, const void *data, static int binfs_unbind(void *handle, FAR struct inode **blkdriver) { - struct binfs_state_s *bm = (struct binfs_state_s*)handle; - fvdbg("Entry\n"); - -#ifdef CONFIG_DEBUG - if (!bm) - { - return -EINVAL; - } -#endif - - /* Check if there are sill any files opened on the filesystem. */ - - /* Release the mountpoint private data */ - - sem_destroy(&bm->bm_sem); return OK; } @@ -540,19 +385,8 @@ static int binfs_unbind(void *handle, FAR struct inode **blkdriver) static int binfs_statfs(struct inode *mountpt, struct statfs *buf) { - struct binfs_state_s *bm; - fvdbg("Entry\n"); - /* Sanity checks */ - - DEBUGASSERT(mountpt && mountpt->i_private); - - /* Get the mountpoint private data from the inode structure */ - - bm = mountpt->i_private; - binfs_semtake(bm); - /* Fill in the statfs info */ memset(buf, 0, sizeof(struct statfs)); @@ -562,8 +396,6 @@ static int binfs_statfs(struct inode *mountpt, struct statfs *buf) buf->f_bfree = 0; buf->f_bavail = 0; buf->f_namelen = NAME_MAX; - - binfs_semgive(bm); return OK; } @@ -576,20 +408,8 @@ static int binfs_statfs(struct inode *mountpt, struct statfs *buf) static int binfs_stat(struct inode *mountpt, const char *relpath, struct stat *buf) { - struct binfs_state_s *bm; - int ret; - fvdbg("Entry\n"); - /* Sanity checks */ - - DEBUGASSERT(mountpt && mountpt->i_private); - - /* Get the mountpoint private data from the inode structure */ - - bm = mountpt->i_private; - binfs_semtake(bm); - /* The requested directory must be the volume-relative "root" directory */ if (relpath && relpath[0] != '\0') @@ -598,8 +418,7 @@ static int binfs_stat(struct inode *mountpt, const char *relpath, struct stat *b if (builtin_isavail(relpath) < 0) { - ret = -ENOENT; - goto errout_with_semaphore; + return -ENOENT; } /* It's a execute-only file name */ @@ -615,14 +434,10 @@ static int binfs_stat(struct inode *mountpt, const char *relpath, struct stat *b /* File/directory size, access block size */ - buf->st_size = 0; - buf->st_blksize = 0; - buf->st_blocks = 0; - ret = OK; - -errout_with_semaphore: - binfs_semgive(bm); - return ret; + buf->st_size = 0; + buf->st_blksize = 0; + buf->st_blocks = 0; + return OK; } /**************************************************************************** |