mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 06:32:32 +08:00
Added opendir, readdir, closedir, etc.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@62 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -31,3 +31,7 @@
|
|||||||
when the timer interrupt is enabled. Seems to be an
|
when the timer interrupt is enabled. Seems to be an
|
||||||
issue when SP enters indirect address space.
|
issue when SP enters indirect address space.
|
||||||
* Documentation updates
|
* Documentation updates
|
||||||
|
|
||||||
|
0.1.2 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
|
||||||
|
* Add dirent.h, opendir(), readdir(), closedir(), etc.
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ defconfig -- This is a configuration file similar to the Linux
|
|||||||
descriptors (one for each open)
|
descriptors (one for each open)
|
||||||
CONFIG_NFILE_STREAMS - The maximum number of streams that
|
CONFIG_NFILE_STREAMS - The maximum number of streams that
|
||||||
can be fopen'ed
|
can be fopen'ed
|
||||||
|
CONFIG_NAME_MAX - The maximum size of a file name.
|
||||||
CONFIG_STDIO_BUFFER_SIZE - Size of the buffer to allocate
|
CONFIG_STDIO_BUFFER_SIZE - Size of the buffer to allocate
|
||||||
on fopen. (Only if CONFIG_NFILE_STREAMS > 0)
|
on fopen. (Only if CONFIG_NFILE_STREAMS > 0)
|
||||||
CONFIG_NUNGET_CHARS - Number of characters that can be
|
CONFIG_NUNGET_CHARS - Number of characters that can be
|
||||||
|
|||||||
@@ -191,6 +191,7 @@ CONFIG_RRLOAD_BINARY=y
|
|||||||
# descriptors (one for each open)
|
# descriptors (one for each open)
|
||||||
# CONFIG_NFILE_STREAMS - The maximum number of streams that
|
# CONFIG_NFILE_STREAMS - The maximum number of streams that
|
||||||
# can be fopen'ed
|
# can be fopen'ed
|
||||||
|
# CONFIG_NAME_MAX - The maximum size of a file name.
|
||||||
# CONFIG_STDIO_BUFFER_SIZE - Size of the buffer to allocate
|
# CONFIG_STDIO_BUFFER_SIZE - Size of the buffer to allocate
|
||||||
# on fopen. (Only if CONFIG_NFILE_STREAMS > 0)
|
# on fopen. (Only if CONFIG_NFILE_STREAMS > 0)
|
||||||
# CONFIG_NUNGET_CHARS - Number of characters that can be
|
# CONFIG_NUNGET_CHARS - Number of characters that can be
|
||||||
@@ -212,6 +213,7 @@ CONFIG_MAX_TASK_ARGS=4
|
|||||||
CONFIG_NPTHREAD_KEYS=4
|
CONFIG_NPTHREAD_KEYS=4
|
||||||
CONFIG_NFILE_DESCRIPTORS=32
|
CONFIG_NFILE_DESCRIPTORS=32
|
||||||
CONFIG_NFILE_STREAMS=16
|
CONFIG_NFILE_STREAMS=16
|
||||||
|
CONFIG_NAME_MAX=32
|
||||||
CONFIG_STDIO_BUFFER_SIZE=1024
|
CONFIG_STDIO_BUFFER_SIZE=1024
|
||||||
CONFIG_NUNGET_CHARS=2
|
CONFIG_NUNGET_CHARS=2
|
||||||
CONFIG_PREALLOC_MQ_MSGS=32
|
CONFIG_PREALLOC_MQ_MSGS=32
|
||||||
|
|||||||
@@ -185,6 +185,7 @@ CONFIG_RRLOAD_BINARY=n
|
|||||||
# descriptors (one for each open)
|
# descriptors (one for each open)
|
||||||
# CONFIG_NFILE_STREAMS - The maximum number of streams that
|
# CONFIG_NFILE_STREAMS - The maximum number of streams that
|
||||||
# can be fopen'ed
|
# can be fopen'ed
|
||||||
|
# CONFIG_NAME_MAX - The maximum size of a file name.
|
||||||
# CONFIG_STDIO_BUFFER_SIZE - Size of the buffer to allocate
|
# CONFIG_STDIO_BUFFER_SIZE - Size of the buffer to allocate
|
||||||
# on fopen. (Only if CONFIG_NFILE_STREAMS > 0)
|
# on fopen. (Only if CONFIG_NFILE_STREAMS > 0)
|
||||||
# CONFIG_NUNGET_CHARS - Number of characters that can be
|
# CONFIG_NUNGET_CHARS - Number of characters that can be
|
||||||
@@ -206,6 +207,7 @@ CONFIG_MAX_TASK_ARGS=4
|
|||||||
CONFIG_NPTHREAD_KEYS=0
|
CONFIG_NPTHREAD_KEYS=0
|
||||||
CONFIG_NFILE_DESCRIPTORS=0
|
CONFIG_NFILE_DESCRIPTORS=0
|
||||||
CONFIG_NFILE_STREAMS=0
|
CONFIG_NFILE_STREAMS=0
|
||||||
|
CONFIG_NAME_MAX=32
|
||||||
CONFIG_STDIO_BUFFER_SIZE=0
|
CONFIG_STDIO_BUFFER_SIZE=0
|
||||||
CONFIG_NUNGET_CHARS=0
|
CONFIG_NUNGET_CHARS=0
|
||||||
CONFIG_PREALLOC_MQ_MSGS=0
|
CONFIG_PREALLOC_MQ_MSGS=0
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ CONFIG_RRLOAD_BINARY=n
|
|||||||
# descriptors (one for each open)
|
# descriptors (one for each open)
|
||||||
# CONFIG_NFILE_STREAMS - The maximum number of streams that
|
# CONFIG_NFILE_STREAMS - The maximum number of streams that
|
||||||
# can be fopen'ed
|
# can be fopen'ed
|
||||||
|
# CONFIG_NAME_MAX - The maximum size of a file name.
|
||||||
# CONFIG_STDIO_BUFFER_SIZE - Size of the buffer to allocate
|
# CONFIG_STDIO_BUFFER_SIZE - Size of the buffer to allocate
|
||||||
# on fopen. (Only if CONFIG_NFILE_STREAMS > 0)
|
# on fopen. (Only if CONFIG_NFILE_STREAMS > 0)
|
||||||
# CONFIG_NUNGET_CHARS - Number of characters that can be
|
# CONFIG_NUNGET_CHARS - Number of characters that can be
|
||||||
@@ -172,6 +173,7 @@ CONFIG_MAX_TASK_ARGS=4
|
|||||||
CONFIG_NPTHREAD_KEYS=4
|
CONFIG_NPTHREAD_KEYS=4
|
||||||
CONFIG_NFILE_DESCRIPTORS=32
|
CONFIG_NFILE_DESCRIPTORS=32
|
||||||
CONFIG_NFILE_STREAMS=16
|
CONFIG_NFILE_STREAMS=16
|
||||||
|
CONFIG_NAME_MAX=32
|
||||||
CONFIG_STDIO_BUFFER_SIZE=1024
|
CONFIG_STDIO_BUFFER_SIZE=1024
|
||||||
CONFIG_NUNGET_CHARS=2
|
CONFIG_NUNGET_CHARS=2
|
||||||
CONFIG_PREALLOC_MQ_MSGS=32
|
CONFIG_PREALLOC_MQ_MSGS=32
|
||||||
|
|||||||
+4
-1
@@ -41,7 +41,10 @@ ASRCS =
|
|||||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||||
|
|
||||||
CSRCS = fs_open.c fs_close.c fs_read.c fs_write.c fs_ioctl.c fs_dup.c \
|
CSRCS = fs_open.c fs_close.c fs_read.c fs_write.c fs_ioctl.c fs_dup.c \
|
||||||
fs_files.c fs_inode.c
|
fs_opendir.c fs_closedir.c fs_readdir.c fs_readdirr.c \
|
||||||
|
fs_seekdir.c fs_telldir.c fs_rewinddir.c fs_files.c \
|
||||||
|
fs_inode.c fs_inodefind.c fs_inodefinddir.c fs_registerinode.c \
|
||||||
|
fs_unregisterinode.c fs_inodeaddref.c fs_inoderelease.c
|
||||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||||
|
|
||||||
SRCS = $(ASRCS) $(CSRCS)
|
SRCS = $(ASRCS) $(CSRCS)
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
/************************************************************
|
||||||
|
* fs_closedir.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Included Files
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <nuttx/fs.h>
|
||||||
|
#include "fs_internal.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: seekdir
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The closedir() function closes the directory stream
|
||||||
|
* associated with 'dirp'. The directory stream
|
||||||
|
* descriptor 'dirp' is not available after this call.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* dirp -- An instance of type DIR created by a previous
|
||||||
|
* call to opendir();
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
* The closedir() function returns 0 on success. On error,
|
||||||
|
* -1 is returned, and errno is set appropriately.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
|
|
||||||
|
int closedir(FAR DIR *dirp)
|
||||||
|
{
|
||||||
|
struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
|
||||||
|
off_t i;
|
||||||
|
|
||||||
|
if (!idir)
|
||||||
|
{
|
||||||
|
*get_errno_ptr() = EBADF;
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release our references on the contained inodes */
|
||||||
|
|
||||||
|
if (idir->root)
|
||||||
|
{
|
||||||
|
inode_release(idir->root);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idir->next)
|
||||||
|
{
|
||||||
|
inode_release(idir->next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then release the container */
|
||||||
|
|
||||||
|
free(idir);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_NFILE_DESCRIPTORS */
|
||||||
+83
-336
@@ -33,10 +33,6 @@
|
|||||||
*
|
*
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
/************************************************************
|
|
||||||
* Compilation Switches
|
|
||||||
************************************************************/
|
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Included Files
|
* Included Files
|
||||||
************************************************************/
|
************************************************************/
|
||||||
@@ -56,9 +52,6 @@
|
|||||||
* Definitions
|
* Definitions
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
#define INODE_SEMGIVE() \
|
|
||||||
sem_post(&tree_sem)
|
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Private Variables
|
* Private Variables
|
||||||
************************************************************/
|
************************************************************/
|
||||||
@@ -75,21 +68,9 @@ FAR struct inode *root_inode = NULL;
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
static void _inode_semtake(void)
|
/************************************************************
|
||||||
{
|
* Name: _inode_compare
|
||||||
/* Take the semaphore (perhaps waiting) */
|
************************************************************/
|
||||||
|
|
||||||
while (sem_wait(&tree_sem) != 0)
|
|
||||||
{
|
|
||||||
/* The only case that an error should occr here is if
|
|
||||||
* the wait was awakened by a signal.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ASSERT(*get_errno_ptr() == EINTR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define _inode_semgive(void) sem_post(&tree_sem)
|
|
||||||
|
|
||||||
static int _inode_compare(const char *fname,
|
static int _inode_compare(const char *fname,
|
||||||
FAR struct inode *node)
|
FAR struct inode *node)
|
||||||
@@ -152,47 +133,77 @@ static int _inode_compare(const char *fname,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _inode_namelen(const char *name)
|
/************************************************************
|
||||||
{
|
* Public Functions
|
||||||
const char *tmp = name;
|
************************************************************/
|
||||||
while(*tmp && *tmp != '/') tmp++;
|
|
||||||
return tmp - name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _inode_namecpy(char *dest, const char *src)
|
/************************************************************
|
||||||
{
|
* Name: fs_initialize
|
||||||
while(*src && *src != '/') *dest++ = *src++;
|
*
|
||||||
*dest='\0';
|
* Description:
|
||||||
}
|
* This is called from the OS initialization logic to configure
|
||||||
|
* the file system.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
static const char *_inode_nextname(const char *name)
|
void fs_initialize(void)
|
||||||
{
|
{
|
||||||
while (*name && *name != '/') name++;
|
/* Initialize the semaphore to one (to support one-at-
|
||||||
if (*name) name++;
|
* a-time access to the inode tree).
|
||||||
return name;
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
static FAR struct inode *_inode_alloc(const char *name,
|
(void)sem_init(&tree_sem, 0, 1);
|
||||||
struct file_operations *fops,
|
|
||||||
mode_t mode, void *private)
|
/* Initialize files array (if it is used) */
|
||||||
{
|
|
||||||
int namelen = _inode_namelen(name);
|
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
||||||
FAR struct inode *node = (FAR struct inode*)malloc(FSNODE_SIZE(namelen));
|
if (files_initialize != NULL)
|
||||||
if (node)
|
|
||||||
{
|
|
||||||
node->i_peer = NULL;
|
|
||||||
node->i_child = NULL;
|
|
||||||
node->i_ops = fops;
|
|
||||||
#ifdef CONFIG_FILE_MODE
|
|
||||||
node->i_mode = mode;
|
|
||||||
#endif
|
#endif
|
||||||
node->i_private = private;
|
{
|
||||||
_inode_namecpy(node->i_name, name);
|
files_initialize();
|
||||||
}
|
}
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static FAR struct inode *_inode_find(const char **path,
|
/************************************************************
|
||||||
|
* Name: inode_semtake
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
void inode_semtake(void)
|
||||||
|
{
|
||||||
|
/* Take the semaphore (perhaps waiting) */
|
||||||
|
|
||||||
|
while (sem_wait(&tree_sem) != 0)
|
||||||
|
{
|
||||||
|
/* The only case that an error should occr here is if
|
||||||
|
* the wait was awakened by a signal.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ASSERT(*get_errno_ptr() == EINTR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: inode_semgive
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
void inode_semgive(void)
|
||||||
|
{
|
||||||
|
sem_post(&tree_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: inode_search
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Find the inode associated with 'path' returning the
|
||||||
|
* inode references and references to its companion nodes.
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The caller holds the tree_sem
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
FAR struct inode *inode_search(const char **path,
|
||||||
FAR struct inode **peer,
|
FAR struct inode **peer,
|
||||||
FAR struct inode **parent)
|
FAR struct inode **parent)
|
||||||
{
|
{
|
||||||
@@ -237,7 +248,7 @@ static FAR struct inode *_inode_find(const char **path,
|
|||||||
* (2) the node we are looking for is "blow" this one.
|
* (2) the node we are looking for is "blow" this one.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
name = _inode_nextname(name);
|
name = inode_nextname(name);
|
||||||
if (!*name)
|
if (!*name)
|
||||||
{
|
{
|
||||||
/* We are at the end of the path, so this must be
|
/* We are at the end of the path, so this must be
|
||||||
@@ -278,296 +289,32 @@ static FAR struct inode *_inode_find(const char **path,
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _inode_insert(FAR struct inode *node,
|
/************************************************************
|
||||||
FAR struct inode *peer,
|
* Name: inode_free
|
||||||
FAR struct inode *parent)
|
************************************************************/
|
||||||
{
|
|
||||||
/* If peer is non-null, then new node simply goes to the right
|
|
||||||
* of that peer node.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (peer)
|
void inode_free(FAR struct inode *node)
|
||||||
{
|
|
||||||
node->i_peer = peer->i_peer;
|
|
||||||
peer->i_peer = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If parent is non-null, then it must go at the head of its
|
|
||||||
* list of children.
|
|
||||||
*/
|
|
||||||
|
|
||||||
else if (parent)
|
|
||||||
{
|
|
||||||
node->i_peer = parent->i_child;
|
|
||||||
parent->i_child = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise, this must be the new root_inode */
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
node->i_peer = root_inode;
|
|
||||||
root_inode = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _inode_remove(struct inode *node,
|
|
||||||
struct inode *peer,
|
|
||||||
struct inode *parent)
|
|
||||||
{
|
|
||||||
/* If peer is non-null, then remove the node from the right of
|
|
||||||
* of that peer node.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (peer)
|
|
||||||
{
|
|
||||||
peer->i_peer = node->i_peer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If parent is non-null, then remove the node from head of
|
|
||||||
* of the list of children.
|
|
||||||
*/
|
|
||||||
|
|
||||||
else if (parent)
|
|
||||||
{
|
|
||||||
parent->i_child = node->i_peer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise, we must be removing the root inode. */
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
root_inode = node->i_peer;
|
|
||||||
}
|
|
||||||
node->i_peer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _inode_free(FAR struct inode *node)
|
|
||||||
{
|
{
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
_inode_free(node->i_peer);
|
inode_free(node->i_peer);
|
||||||
_inode_free(node->i_child);
|
inode_free(node->i_child);
|
||||||
free(node);
|
free(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Public Functions
|
* Name: inode_nextname
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Given a path with node names separated by '/', return
|
||||||
|
* the next node name.
|
||||||
|
*
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
/* This is called from the OS initialization logic to configure
|
const char *inode_nextname(const char *name)
|
||||||
* the file system.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void fs_initialize(void)
|
|
||||||
{
|
{
|
||||||
/* Initialize the semaphore to one (to support one-at-
|
while (*name && *name != '/') name++;
|
||||||
* a-time access to the inode tree).
|
if (*name) name++;
|
||||||
*/
|
return name;
|
||||||
|
|
||||||
(void)sem_init(&tree_sem, 0, 1);
|
|
||||||
|
|
||||||
/* Initialize files array (if it is used) */
|
|
||||||
|
|
||||||
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
|
||||||
if (files_initialize != NULL)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
files_initialize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is called from the open() logic to get a reference
|
|
||||||
* to the inode associatged with a path.
|
|
||||||
*/
|
|
||||||
|
|
||||||
FAR struct inode *inode_find(const char *path)
|
|
||||||
{
|
|
||||||
FAR struct inode *node;
|
|
||||||
|
|
||||||
if (!*path || path[0] != '/')
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the node matching the path. If found,
|
|
||||||
* increment the count of references on the node.
|
|
||||||
*/
|
|
||||||
|
|
||||||
_inode_semtake();
|
|
||||||
node = _inode_find(&path, (FAR void*)NULL, (FAR void*)NULL);
|
|
||||||
if (node) node->i_crefs++;
|
|
||||||
_inode_semgive();
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Increment the reference count on an inode (as when a file
|
|
||||||
* descriptor is dup'ed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void inode_addref(FAR struct inode *inode)
|
|
||||||
{
|
|
||||||
if (inode)
|
|
||||||
{
|
|
||||||
_inode_semtake();
|
|
||||||
inode->i_crefs++;
|
|
||||||
_inode_semgive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is called from close() logic when it no longer refers
|
|
||||||
* to the inode.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void inode_release(FAR struct inode *node)
|
|
||||||
{
|
|
||||||
if (node)
|
|
||||||
{
|
|
||||||
/* Decrement the references of the inode */
|
|
||||||
|
|
||||||
_inode_semtake();
|
|
||||||
if (node->i_crefs)
|
|
||||||
{
|
|
||||||
node->i_crefs--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the subtree was previously deleted and the reference
|
|
||||||
* count has decrement to zero, then delete the inode
|
|
||||||
* now.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (node->i_crefs <= 0 && (node->i_flags & FSNODEFLAG_DELETED) != 0)
|
|
||||||
{
|
|
||||||
_inode_semgive();
|
|
||||||
_inode_free(node->i_child);
|
|
||||||
free(node);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_inode_semgive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
STATUS register_inode(const char *path,
|
|
||||||
struct file_operations *fops,
|
|
||||||
mode_t mode, void *private)
|
|
||||||
{
|
|
||||||
const char *name = path;
|
|
||||||
FAR struct inode *left;
|
|
||||||
FAR struct inode *parent;
|
|
||||||
|
|
||||||
if (!*path || path[0] != '/')
|
|
||||||
{
|
|
||||||
return ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the location to insert the new subtree */
|
|
||||||
|
|
||||||
_inode_semtake();
|
|
||||||
if (_inode_find(&name, &left, &parent) != NULL)
|
|
||||||
{
|
|
||||||
/* Is is an error if the node already exists in the tree */
|
|
||||||
|
|
||||||
_inode_semgive();
|
|
||||||
return ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now we now where to insert the subtree */
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
FAR struct inode *node;
|
|
||||||
|
|
||||||
/* Create a new node -- we need to know if this is the
|
|
||||||
* the leaf node or some intermediary. We can find this
|
|
||||||
* by looking at the next name.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const char *next_name = _inode_nextname(name);
|
|
||||||
if (*next_name)
|
|
||||||
{
|
|
||||||
/* Insert an operationless node */
|
|
||||||
|
|
||||||
node = _inode_alloc(name, NULL, mode, NULL);
|
|
||||||
if (node)
|
|
||||||
{
|
|
||||||
_inode_insert(node, left, parent);
|
|
||||||
|
|
||||||
/* Set up for the next time through the loop */
|
|
||||||
|
|
||||||
name = next_name;
|
|
||||||
left = NULL;
|
|
||||||
parent = node;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
node = _inode_alloc(name, fops, mode, private);
|
|
||||||
if (node)
|
|
||||||
{
|
|
||||||
_inode_insert(node, left, parent);
|
|
||||||
_inode_semgive();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We get here on failures to allocate node memory */
|
|
||||||
|
|
||||||
_inode_semgive();
|
|
||||||
return ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATUS unregister_inode(const char *path)
|
|
||||||
{
|
|
||||||
const char *name = path;
|
|
||||||
FAR struct inode *node;
|
|
||||||
FAR struct inode *left;
|
|
||||||
FAR struct inode *parent;
|
|
||||||
|
|
||||||
if (*path && path[0] == '/')
|
|
||||||
{
|
|
||||||
return ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the node to delete */
|
|
||||||
|
|
||||||
_inode_semtake();
|
|
||||||
node = _inode_find(&name, &left, &parent);
|
|
||||||
if (node)
|
|
||||||
{
|
|
||||||
/* Found it, now remove it from the tree */
|
|
||||||
|
|
||||||
_inode_remove(node, left, parent);
|
|
||||||
|
|
||||||
/* We cannot delete it if there reference to the inode */
|
|
||||||
|
|
||||||
if (node->i_crefs)
|
|
||||||
{
|
|
||||||
/* In that case, we will mark it deleted, when the FS
|
|
||||||
* releases the inode, we will then, finally delete
|
|
||||||
* the subtree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
node->i_flags |= FSNODEFLAG_DELETED;
|
|
||||||
_inode_semgive();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* And delete it now -- recursively to delete all of its children */
|
|
||||||
|
|
||||||
_inode_semgive();
|
|
||||||
_inode_free(node->i_child);
|
|
||||||
free(node);
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The node does not exist or it has references */
|
|
||||||
_inode_semgive();
|
|
||||||
return ERROR;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/************************************************************
|
||||||
|
* fs_inodeaddref.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Included Files
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <nuttx/fs.h>
|
||||||
|
#include "fs_internal.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Definitions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Variables
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Variables
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: inode_addref
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Increment the reference count on an inode (as when a file
|
||||||
|
* descriptor is dup'ed.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
void inode_addref(FAR struct inode *inode)
|
||||||
|
{
|
||||||
|
if (inode)
|
||||||
|
{
|
||||||
|
inode_semtake();
|
||||||
|
inode->i_crefs++;
|
||||||
|
inode_semgive();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
/************************************************************
|
||||||
|
* fs_inodefind.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Included Files
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <nuttx/fs.h>
|
||||||
|
#include "fs_internal.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Definitions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Variables
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Variables
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: inode_find
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This is called from the open() logic to get a reference
|
||||||
|
* to the inode associated with a path.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
FAR struct inode *inode_find(const char *path)
|
||||||
|
{
|
||||||
|
FAR struct inode *node;
|
||||||
|
|
||||||
|
if (!*path || path[0] != '/')
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the node matching the path. If found,
|
||||||
|
* increment the count of references on the node.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inode_semtake();
|
||||||
|
node = inode_search(&path, (FAR void*)NULL, (FAR void*)NULL);
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
node->i_crefs++;
|
||||||
|
}
|
||||||
|
inode_semgive();
|
||||||
|
return node;
|
||||||
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
/************************************************************
|
||||||
|
* fs_inodefinddir.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Included Files
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <nuttx/fs.h>
|
||||||
|
#include "fs_internal.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Definitions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Variables
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Variables
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: inode_finddir
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
FAR struct inode *inode_finddir(const char *path)
|
||||||
|
{
|
||||||
|
FAR struct inode *node;
|
||||||
|
FAR struct inode *child = NULL;
|
||||||
|
|
||||||
|
if (!*path || path[0] != '/')
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the node matching the path. */
|
||||||
|
|
||||||
|
inode_semtake();
|
||||||
|
node = inode_search(&path, (FAR void*)NULL, (FAR void*)NULL);
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
/* Does the inode have a child? If so that the child
|
||||||
|
* would be the 'head' of a list of nodes under the
|
||||||
|
* directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
child = node->i_child;
|
||||||
|
if (child)
|
||||||
|
{
|
||||||
|
/* If found, then increment the count of
|
||||||
|
* references on the child node.
|
||||||
|
*/
|
||||||
|
|
||||||
|
child->i_crefs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inode_semgive();
|
||||||
|
return child;
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
/************************************************************
|
||||||
|
* fs_inoderelease.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Included Files
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <nuttx/fs.h>
|
||||||
|
#include "fs_internal.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Definitions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Variables
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Variables
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: inode_release
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This is called from close() logic when it no longer refers
|
||||||
|
* to the inode.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
void inode_release(FAR struct inode *node)
|
||||||
|
{
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
/* Decrement the references of the inode */
|
||||||
|
|
||||||
|
inode_semtake();
|
||||||
|
if (node->i_crefs)
|
||||||
|
{
|
||||||
|
node->i_crefs--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the subtree was previously deleted and the reference
|
||||||
|
* count has decrement to zero, then delete the inode
|
||||||
|
* now.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (node->i_crefs <= 0 && (node->i_flags & FSNODEFLAG_DELETED) != 0)
|
||||||
|
{
|
||||||
|
inode_semgive();
|
||||||
|
inode_free(node->i_child);
|
||||||
|
free(node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inode_semgive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
#include <nuttx/fs.h>
|
#include <nuttx/fs.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <nuttx/compiler.h>
|
#include <nuttx/compiler.h>
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
@@ -54,6 +55,20 @@
|
|||||||
* Public Types
|
* Public Types
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
|
/* The internal representation of type DIR is just a
|
||||||
|
* container for an inode reference and a dirent structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct internal_dir_s
|
||||||
|
{
|
||||||
|
struct inode *root; /* The start inode (in case we
|
||||||
|
* rewind) */
|
||||||
|
struct inode *next; /* The inode to use for the next call
|
||||||
|
* to readdir() */
|
||||||
|
struct dirent dir; /* Populated using inode when readdir
|
||||||
|
* is called */
|
||||||
|
};
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Global Variables
|
* Global Variables
|
||||||
************************************************************/
|
************************************************************/
|
||||||
@@ -74,8 +89,29 @@ extern "C" {
|
|||||||
|
|
||||||
/* fs_inode.c ***********************************************/
|
/* fs_inode.c ***********************************************/
|
||||||
|
|
||||||
|
EXTERN void inode_semtake(void);
|
||||||
|
EXTERN void inode_semgive(void);
|
||||||
|
EXTERN FAR struct inode *inode_search(const char **path,
|
||||||
|
FAR struct inode **peer,
|
||||||
|
FAR struct inode **parent);
|
||||||
|
EXTERN void inode_free(FAR struct inode *node);
|
||||||
|
EXTERN const char *inode_nextname(const char *name);
|
||||||
|
|
||||||
|
|
||||||
|
/* fs_inodefind.c ********************************************/
|
||||||
|
|
||||||
EXTERN FAR struct inode *inode_find(const char *path);
|
EXTERN FAR struct inode *inode_find(const char *path);
|
||||||
|
|
||||||
|
/* fs_inodefinddir.c *****************************************/
|
||||||
|
|
||||||
|
EXTERN FAR struct inode *inode_finddir(const char *path);
|
||||||
|
|
||||||
|
/* fs_inodeaddref.c ******************************************/
|
||||||
|
|
||||||
EXTERN void inode_addref(FAR struct inode *inode);
|
EXTERN void inode_addref(FAR struct inode *inode);
|
||||||
|
|
||||||
|
/* fs_inoderelease.c *****************************************/
|
||||||
|
|
||||||
EXTERN void inode_release(FAR struct inode *inode);
|
EXTERN void inode_release(FAR struct inode *inode);
|
||||||
|
|
||||||
/* fs_files.c ***********************************************/
|
/* fs_files.c ***********************************************/
|
||||||
|
|||||||
@@ -33,10 +33,6 @@
|
|||||||
*
|
*
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
/************************************************************
|
|
||||||
* Compilation Switches
|
|
||||||
************************************************************/
|
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Included Files
|
* Included Files
|
||||||
************************************************************/
|
************************************************************/
|
||||||
@@ -50,7 +46,6 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#endif
|
#endif
|
||||||
#include <nuttx/fs.h>
|
#include <nuttx/fs.h>
|
||||||
#include <errno.h>
|
|
||||||
#include "fs_internal.h"
|
#include "fs_internal.h"
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
|
|||||||
+126
@@ -0,0 +1,126 @@
|
|||||||
|
/************************************************************
|
||||||
|
* fs_opendir.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Included Files
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <nuttx/fs.h>
|
||||||
|
#include "fs_internal.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: opendir
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The opendir() function opens a directory stream
|
||||||
|
* corresponding to the directory name, and returns a
|
||||||
|
* pointer to the directory stream. The stream is
|
||||||
|
* positioned at the first entry in the directory.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* path -- the directory to open
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
* The opendir() function returns a pointer to the
|
||||||
|
* directory stream. On error, NULL is returned, and
|
||||||
|
* errno is set appropriately.
|
||||||
|
*
|
||||||
|
* EACCES - Permission denied.
|
||||||
|
* EMFILE - Too many file descriptors in use by process.
|
||||||
|
* ENFILE - Too many files are currently open in the
|
||||||
|
* system.
|
||||||
|
* ENOENT - Directory does not exist, or name is an empty
|
||||||
|
* string.
|
||||||
|
* ENOMEM - Insufficient memory to complete the operation.
|
||||||
|
* ENOTDIR - 'path' is not a directory.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
|
|
||||||
|
FAR DIR *opendir(const char *path)
|
||||||
|
{
|
||||||
|
FAR struct inode *inode;
|
||||||
|
FAR struct internal_dir_s *dir;
|
||||||
|
|
||||||
|
/* Get an inode corresponding to the path. On successful
|
||||||
|
* return, we will hold on reference count on the inode.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inode = inode_finddir(path);
|
||||||
|
if (!inode)
|
||||||
|
{
|
||||||
|
/* 'path' is not a directory.*/
|
||||||
|
|
||||||
|
*get_errno_ptr() = ENOTDIR;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a type DIR -- which is little more than an inode
|
||||||
|
* container.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dir = (FAR struct internal_dir_s *)zmalloc(sizeof(struct internal_dir_s *));
|
||||||
|
if (!dir)
|
||||||
|
{
|
||||||
|
/* Insufficient memory to complete the operation.*/
|
||||||
|
|
||||||
|
*get_errno_ptr() = ENOMEM;
|
||||||
|
inode_release(inode);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Populate the DIR structure and return it to the caller */
|
||||||
|
|
||||||
|
dir->root = inode; /* Save where we started in case we rewind */
|
||||||
|
inode_addref(inode); /* Now we have two references on inode */
|
||||||
|
dir->next = inode; /* This is the next node to use for readdir() */
|
||||||
|
return ((DIR*)dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_NFILE_DESCRIPTORS */
|
||||||
+145
@@ -0,0 +1,145 @@
|
|||||||
|
/************************************************************
|
||||||
|
* fs_readdir.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Included Files
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <nuttx/fs.h>
|
||||||
|
#include "fs_internal.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: readdir
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The readdir() function returns a pointer to a dirent
|
||||||
|
* structure representing the next directory entry in the
|
||||||
|
* directory stream pointed to by dir. It returns NULL on
|
||||||
|
* reaching the end-of-file or if an error occurred.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* dirp -- An instance of type DIR created by a previous
|
||||||
|
* call to opendir();
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
* The readdir() function returns a pointer to a dirent
|
||||||
|
* structure, or NULL if an error occurs or end-of-file
|
||||||
|
* is reached. On error, errno is set appropriately.
|
||||||
|
*
|
||||||
|
* EBADF - Invalid directory stream descriptor dir
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
|
|
||||||
|
FAR struct dirent *readdir(DIR *dirp)
|
||||||
|
{
|
||||||
|
FAR struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
|
||||||
|
FAR struct inode *prev;
|
||||||
|
|
||||||
|
if (!idir)
|
||||||
|
{
|
||||||
|
*get_errno_ptr() = EBADF;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we are at the end of the list */
|
||||||
|
|
||||||
|
if (!idir->next)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the inode name into the dirent structure */
|
||||||
|
|
||||||
|
strncpy(idir->dir.d_name, idir->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->next->i_ops)
|
||||||
|
{
|
||||||
|
idir->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->next->i_child || !idir->next->i_ops)
|
||||||
|
{
|
||||||
|
idir->dir.d_type |= DTYPE_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now get the inode to vist next time that readdir() is called */
|
||||||
|
|
||||||
|
inode_semtake();
|
||||||
|
|
||||||
|
prev = idir->next;
|
||||||
|
idir->next = prev->i_peer; /* The next node to visit */
|
||||||
|
|
||||||
|
if (idir->next)
|
||||||
|
{
|
||||||
|
/* Increment the reference count on this next node */
|
||||||
|
|
||||||
|
idir->next->i_crefs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
inode_semgive();
|
||||||
|
|
||||||
|
if (prev)
|
||||||
|
{
|
||||||
|
inode_release(prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return &idir->dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_NFILE_DESCRIPTORS */
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
/************************************************************
|
||||||
|
* fs_readdirr.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Included Files
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <nuttx/fs.h>
|
||||||
|
#include "fs_internal.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: readdir_r
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The readdir() function returns a pointer to a dirent
|
||||||
|
* structure representing the next directory entry in the
|
||||||
|
* directory stream pointed to by dir. It returns NULL on
|
||||||
|
* reaching the end-of-file or if an error occurred.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* dirp -- An instance of type DIR created by a previous
|
||||||
|
* call to opendir();
|
||||||
|
* entry -- The storage pointed to by entry must be large
|
||||||
|
* enough for a dirent with an array of char d_name
|
||||||
|
* members containing at least {NAME_MAX}+1 elements.
|
||||||
|
* result -- Upon successful return, the pointer returned
|
||||||
|
* at *result shall have the same value as the
|
||||||
|
* argument entry. Upon reaching the end of the directory
|
||||||
|
* stream, this pointer shall have the value NULL.
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
* If successful, the readdir_r() function return s zero;
|
||||||
|
* otherwise, an error number is returned to indicate the
|
||||||
|
* error.
|
||||||
|
*
|
||||||
|
* EBADF - Invalid directory stream descriptor dir
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
|
|
||||||
|
int readdir_r(FAR DIR *dirp, FAR struct dirent *entry,
|
||||||
|
FAR struct dirent **result)
|
||||||
|
{
|
||||||
|
struct dirent *tmp;
|
||||||
|
|
||||||
|
*get_errno_ptr() = 0;
|
||||||
|
tmp = readdir(dirp);
|
||||||
|
if (!tmp)
|
||||||
|
{
|
||||||
|
int error = *get_errno_ptr();
|
||||||
|
if (!error)
|
||||||
|
{
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
*result = NULL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry)
|
||||||
|
{
|
||||||
|
memcpy(entry, tmp, sizeof(struct dirent));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
*result = entry;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_NFILE_DESCRIPTORS */
|
||||||
@@ -0,0 +1,222 @@
|
|||||||
|
/************************************************************
|
||||||
|
* fs_registerinode.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Included Files
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <nuttx/fs.h>
|
||||||
|
#include "fs_internal.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Definitions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Variables
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Variables
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: inode_namelen
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
static int inode_namelen(const char *name)
|
||||||
|
{
|
||||||
|
const char *tmp = name;
|
||||||
|
while(*tmp && *tmp != '/') tmp++;
|
||||||
|
return tmp - name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: inode_namecpy
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
static void inode_namecpy(char *dest, const char *src)
|
||||||
|
{
|
||||||
|
while(*src && *src != '/') *dest++ = *src++;
|
||||||
|
*dest='\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: inode_alloc
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
static FAR struct inode *inode_alloc(const char *name,
|
||||||
|
struct file_operations *fops,
|
||||||
|
mode_t mode, void *private)
|
||||||
|
{
|
||||||
|
int namelen = inode_namelen(name);
|
||||||
|
FAR struct inode *node = (FAR struct inode*)malloc(FSNODE_SIZE(namelen));
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
node->i_peer = NULL;
|
||||||
|
node->i_child = NULL;
|
||||||
|
node->i_ops = fops;
|
||||||
|
#ifdef CONFIG_FILE_MODE
|
||||||
|
node->i_mode = mode;
|
||||||
|
#endif
|
||||||
|
node->i_private = private;
|
||||||
|
inode_namecpy(node->i_name, name);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: inode_insert
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
static void inode_insert(FAR struct inode *node,
|
||||||
|
FAR struct inode *peer,
|
||||||
|
FAR struct inode *parent)
|
||||||
|
{
|
||||||
|
/* If peer is non-null, then new node simply goes to the right
|
||||||
|
* of that peer node.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (peer)
|
||||||
|
{
|
||||||
|
node->i_peer = peer->i_peer;
|
||||||
|
peer->i_peer = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If parent is non-null, then it must go at the head of its
|
||||||
|
* list of children.
|
||||||
|
*/
|
||||||
|
|
||||||
|
else if (parent)
|
||||||
|
{
|
||||||
|
node->i_peer = parent->i_child;
|
||||||
|
parent->i_child = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, this must be the new root_inode */
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node->i_peer = root_inode;
|
||||||
|
root_inode = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: register_inode
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
STATUS register_inode(const char *path,
|
||||||
|
struct file_operations *fops,
|
||||||
|
mode_t mode, void *private)
|
||||||
|
{
|
||||||
|
const char *name = path;
|
||||||
|
FAR struct inode *left;
|
||||||
|
FAR struct inode *parent;
|
||||||
|
|
||||||
|
if (!*path || path[0] != '/')
|
||||||
|
{
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the location to insert the new subtree */
|
||||||
|
|
||||||
|
inode_semtake();
|
||||||
|
if (inode_search(&name, &left, &parent) != NULL)
|
||||||
|
{
|
||||||
|
/* Is is an error if the node already exists in the tree */
|
||||||
|
|
||||||
|
inode_semgive();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we now where to insert the subtree */
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
FAR struct inode *node;
|
||||||
|
|
||||||
|
/* Create a new node -- we need to know if this is the
|
||||||
|
* the leaf node or some intermediary. We can find this
|
||||||
|
* by looking at the next name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const char *next_name = inode_nextname(name);
|
||||||
|
if (*next_name)
|
||||||
|
{
|
||||||
|
/* Insert an operationless node */
|
||||||
|
|
||||||
|
node = inode_alloc(name, NULL, mode, NULL);
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
inode_insert(node, left, parent);
|
||||||
|
|
||||||
|
/* Set up for the next time through the loop */
|
||||||
|
|
||||||
|
name = next_name;
|
||||||
|
left = NULL;
|
||||||
|
parent = node;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node = inode_alloc(name, fops, mode, private);
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
inode_insert(node, left, parent);
|
||||||
|
inode_semgive();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We get here on failures to allocate node memory */
|
||||||
|
|
||||||
|
inode_semgive();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
/************************************************************
|
||||||
|
* fs_rewinddir.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Included Files
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <nuttx/fs.h>
|
||||||
|
#include "fs_internal.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: rewinddir
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The rewinddir() function resets the position of the
|
||||||
|
* directory stream dir to the beginning of the directory.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* dirp -- An instance of type DIR created by a previous
|
||||||
|
* call to opendir();
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
|
|
||||||
|
void rewinddir(FAR DIR *dirp)
|
||||||
|
{
|
||||||
|
struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
|
||||||
|
struct inode *prev;
|
||||||
|
|
||||||
|
if (idir)
|
||||||
|
{
|
||||||
|
inode_semtake();
|
||||||
|
|
||||||
|
prev = idir->next;
|
||||||
|
idir->next = idir->root; /* The next node to visit */
|
||||||
|
|
||||||
|
if (idir->next)
|
||||||
|
{
|
||||||
|
/* Increment the reference count on this next node */
|
||||||
|
|
||||||
|
idir->next->i_crefs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
inode_semgive();
|
||||||
|
|
||||||
|
if (prev)
|
||||||
|
{
|
||||||
|
inode_release(prev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_NFILE_DESCRIPTORS */
|
||||||
+117
@@ -0,0 +1,117 @@
|
|||||||
|
/************************************************************
|
||||||
|
* fs_seekdir.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Included Files
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <nuttx/fs.h>
|
||||||
|
#include "fs_internal.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: seekdir
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The seekdir() function sets the location in the
|
||||||
|
* directory stream from which the next readdir() call will
|
||||||
|
* start. seekdir() should be used with an offset returned
|
||||||
|
* by telldir().
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* dirp -- An instance of type DIR created by a previous
|
||||||
|
* call to opendir();
|
||||||
|
* offset -- offset to seek to
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
|
|
||||||
|
void seekdir(FAR DIR *dirp, off_t offset)
|
||||||
|
{
|
||||||
|
struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
|
||||||
|
struct inode *curr;
|
||||||
|
struct inode *prev;
|
||||||
|
off_t i;
|
||||||
|
|
||||||
|
if (idir)
|
||||||
|
{
|
||||||
|
/* Traverse the peer list starting at the 'root' of the
|
||||||
|
* the list until we find the node at 'offset". If devices
|
||||||
|
* are being registered and unregistered, then this can
|
||||||
|
* be a very unpredictable operation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inode_semtake();
|
||||||
|
for (i = 0, curr = idir->root;
|
||||||
|
curr && i != offset;
|
||||||
|
i++, curr = curr->i_peer);
|
||||||
|
|
||||||
|
/* Now get the inode to vist next time that readdir() is called */
|
||||||
|
|
||||||
|
prev = idir->next;
|
||||||
|
idir->next = curr; /* The next node to visit */
|
||||||
|
|
||||||
|
if (curr)
|
||||||
|
{
|
||||||
|
/* Increment the reference count on this next node */
|
||||||
|
|
||||||
|
curr->i_crefs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
inode_semgive();
|
||||||
|
|
||||||
|
if (prev)
|
||||||
|
{
|
||||||
|
inode_release(prev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_NFILE_DESCRIPTORS */
|
||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
/************************************************************
|
||||||
|
* fs_telldir.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Included Files
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <nuttx/fs.h>
|
||||||
|
#include "fs_internal.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: telldir
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The telldir() function returns the current location
|
||||||
|
* associated with the directory stream dirp.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* dirp -- An instance of type DIR created by a previous
|
||||||
|
* call to opendir();
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
* On success, the telldir() function returns the current
|
||||||
|
* location in the directory stream. On error, -1 is
|
||||||
|
* returned, and errno is set appropriately.
|
||||||
|
*
|
||||||
|
* EBADF - Invalid directory stream descriptor dir
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
|
|
||||||
|
off_t telldir(FAR DIR *dirp)
|
||||||
|
{
|
||||||
|
struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
|
||||||
|
struct inode *curr;
|
||||||
|
off_t offs;
|
||||||
|
|
||||||
|
if (!idir)
|
||||||
|
{
|
||||||
|
*get_errno_ptr() = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Traverse the peer list starting at the 'root' of the
|
||||||
|
* the list until we find the 'next' node. If devices
|
||||||
|
* are being registered and unregistered, then this can
|
||||||
|
* be a very unpredictable operation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inode_semtake();
|
||||||
|
for (offs = 0, curr = idir->root;
|
||||||
|
curr && curr != idir->next;
|
||||||
|
offs++, curr = curr->i_peer);
|
||||||
|
|
||||||
|
/* We should have an offset now corresponding to idir->next.*/
|
||||||
|
|
||||||
|
inode_semgive();
|
||||||
|
return offs;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_NFILE_DESCRIPTORS */
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/************************************************************
|
||||||
|
* fs_unregisterinode.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Included Files
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <nuttx/fs.h>
|
||||||
|
#include "fs_internal.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Definitions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Variables
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Variables
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Private Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: inode_remove
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
static void inode_remove(struct inode *node,
|
||||||
|
struct inode *peer,
|
||||||
|
struct inode *parent)
|
||||||
|
{
|
||||||
|
/* If peer is non-null, then remove the node from the right of
|
||||||
|
* of that peer node.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (peer)
|
||||||
|
{
|
||||||
|
peer->i_peer = node->i_peer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If parent is non-null, then remove the node from head of
|
||||||
|
* of the list of children.
|
||||||
|
*/
|
||||||
|
|
||||||
|
else if (parent)
|
||||||
|
{
|
||||||
|
parent->i_child = node->i_peer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, we must be removing the root inode. */
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
root_inode = node->i_peer;
|
||||||
|
}
|
||||||
|
node->i_peer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Functions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: unregister_inode
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
STATUS unregister_inode(const char *path)
|
||||||
|
{
|
||||||
|
const char *name = path;
|
||||||
|
FAR struct inode *node;
|
||||||
|
FAR struct inode *left;
|
||||||
|
FAR struct inode *parent;
|
||||||
|
|
||||||
|
if (*path && path[0] == '/')
|
||||||
|
{
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the node to delete */
|
||||||
|
|
||||||
|
inode_semtake();
|
||||||
|
node = inode_search(&name, &left, &parent);
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
/* Found it, now remove it from the tree */
|
||||||
|
|
||||||
|
inode_remove(node, left, parent);
|
||||||
|
|
||||||
|
/* We cannot delete it if there reference to the inode */
|
||||||
|
|
||||||
|
if (node->i_crefs)
|
||||||
|
{
|
||||||
|
/* In that case, we will mark it deleted, when the FS
|
||||||
|
* releases the inode, we will then, finally delete
|
||||||
|
* the subtree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
node->i_flags |= FSNODEFLAG_DELETED;
|
||||||
|
inode_semgive();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* And delete it now -- recursively to delete all of its children */
|
||||||
|
|
||||||
|
inode_semgive();
|
||||||
|
inode_free(node->i_child);
|
||||||
|
free(node);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The node does not exist or it has references */
|
||||||
|
|
||||||
|
inode_semgive();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
/************************************************************
|
||||||
|
* dirent.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#ifndef __DIRENT_H
|
||||||
|
#define __DIRENT_H
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Included Files
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Definitions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/* File type code for the d_type field in dirent struct.
|
||||||
|
* Note that because of the simplified filesystem organization
|
||||||
|
* of NuttX, an inode can be BOTH a file and a directory
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DTYPE_FILE 0x01
|
||||||
|
#define DTYPE_DIRECTORY 0x02
|
||||||
|
|
||||||
|
#define DIRENT_ISFILE(dtype) (((dtype) & DTYPE_FILE) != )
|
||||||
|
#define DIRENT_ISDIRECTORY(dtype) (((dtype) & DTYPE_DIRECTORY) != )
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Type Definitions
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/* The POSIX specification requires that the caller of readdir_r
|
||||||
|
* provide storage "large enough for a dirent with the d_name
|
||||||
|
* member and an array of char containing at least {NAME_MAX}
|
||||||
|
* plus one elements.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct dirent
|
||||||
|
{
|
||||||
|
ubyte d_type; /* type of file */
|
||||||
|
char d_name[NAME_MAX+1]; /* filename */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void DIR;
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Variables
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Public Function Prototypes
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#undef EXTERN
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define EXTERN extern "C"
|
||||||
|
extern "C" {
|
||||||
|
#else
|
||||||
|
#define EXTERN extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* POSIX-like File System Interfaces */
|
||||||
|
|
||||||
|
EXTERN int closedir(DIR *dirp);
|
||||||
|
EXTERN FAR DIR *opendir(const char *path);
|
||||||
|
EXTERN FAR struct dirent *readdir(FAR DIR *dirp);
|
||||||
|
EXTERN int readdir_r(FAR DIR *dirp, FAR struct dirent *entry,
|
||||||
|
FAR struct dirent **result);
|
||||||
|
EXTERN void rewinddir(FAR DIR *dirp);
|
||||||
|
EXTERN void seekdir(FAR DIR *dirp, int loc);
|
||||||
|
EXTERN int telldir(FAR DIR *dirp);
|
||||||
|
|
||||||
|
#undef EXTERN
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __DIRENT_H */
|
||||||
@@ -40,10 +40,19 @@
|
|||||||
* Included Files
|
* Included Files
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
/* Architecture specific limits */
|
||||||
|
|
||||||
#include <arch/limits.h>
|
#include <arch/limits.h>
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Definitions
|
* Definitions
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
|
/* Configurable limits */
|
||||||
|
|
||||||
|
#define NAME_MAX CONFIG_NAME_MAX
|
||||||
|
#define MAXNAMELEN CONFIG_NAME_MAX
|
||||||
|
|
||||||
#endif /* __LIMITS_H */
|
#endif /* __LIMITS_H */
|
||||||
|
|||||||
@@ -92,11 +92,6 @@
|
|||||||
#define FILE_BUF_SIZE (4 * SECTOR_ALIGN_BYTES)
|
#define FILE_BUF_SIZE (4 * SECTOR_ALIGN_BYTES)
|
||||||
#define FILE_BUF_ALIGN_BYTES 16
|
#define FILE_BUF_ALIGN_BYTES 16
|
||||||
|
|
||||||
/* File type code for the EntryType field in dirent struct */
|
|
||||||
|
|
||||||
#define FS_FILE_TYPE 0
|
|
||||||
#define FS_DIRECTORY_TYPE 1
|
|
||||||
|
|
||||||
/* The first three _iob entries are reserved for standard I/O */
|
/* The first three _iob entries are reserved for standard I/O */
|
||||||
|
|
||||||
#define stdin (&sched_getstreams()->sl_streams[0])
|
#define stdin (&sched_getstreams()->sl_streams[0])
|
||||||
@@ -119,38 +114,6 @@
|
|||||||
* Public Type Definitions
|
* Public Type Definitions
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
/* The POSIX specification requires that the caller of readdir_r
|
|
||||||
* provide storage "large enough for a dirent with the d_name
|
|
||||||
* member and an array of char containing at least {NAME_MAX}
|
|
||||||
* plus one elements. The legacy dirent structure does not
|
|
||||||
* contain such an array. The legacy dirent structure is
|
|
||||||
* renamed _dirent below.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct _dirent
|
|
||||||
{
|
|
||||||
FAR char *d_name; /* name of directory entry */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dirent
|
|
||||||
{
|
|
||||||
FAR char *d_name; /* A pointer to d_szname */
|
|
||||||
char d_szname[NAME_MAX+1]; /* name of the directory entry */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned char EntryType; /* FS_FILE_TYPE or FS_DIRECTORY_TYPE */
|
|
||||||
char szName[NAME_MAX]; /* name of the directory entry */
|
|
||||||
} fsdirent;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned long inode;
|
|
||||||
int generation;
|
|
||||||
FAR char *filename;
|
|
||||||
} HANDLE_TO_NAME_IOCTL;
|
|
||||||
|
|
||||||
struct stat
|
struct stat
|
||||||
{
|
{
|
||||||
dev_t st_dev; /* ID of device containing a */
|
dev_t st_dev; /* ID of device containing a */
|
||||||
@@ -189,8 +152,6 @@ struct statfs
|
|||||||
|
|
||||||
typedef FAR struct file_struct FILE;
|
typedef FAR struct file_struct FILE;
|
||||||
|
|
||||||
typedef void DIR;
|
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Public Variables
|
* Public Variables
|
||||||
************************************************************/
|
************************************************************/
|
||||||
@@ -239,7 +200,6 @@ EXTERN int vsprintf(char *buf, const char *s, va_list ap);
|
|||||||
|
|
||||||
EXTERN int chdir(const char *path);
|
EXTERN int chdir(const char *path);
|
||||||
EXTERN int close(int fd);
|
EXTERN int close(int fd);
|
||||||
EXTERN int closedir(DIR *dirp);
|
|
||||||
EXTERN int creat(const char *path, mode_t mode);
|
EXTERN int creat(const char *path, mode_t mode);
|
||||||
EXTERN FILE *fdopen(int fd, const char *type);
|
EXTERN FILE *fdopen(int fd, const char *type);
|
||||||
EXTERN int fstat(int fd, FAR struct stat *buf);
|
EXTERN int fstat(int fd, FAR struct stat *buf);
|
||||||
@@ -248,16 +208,10 @@ EXTERN int ioctl(int fd, int req, unsigned long arg);
|
|||||||
EXTERN off_t lseek(int fd, off_t offset, int whence);
|
EXTERN off_t lseek(int fd, off_t offset, int whence);
|
||||||
EXTERN int mkdir(const char *path, mode_t mode);
|
EXTERN int mkdir(const char *path, mode_t mode);
|
||||||
EXTERN int open(const char *path, int oflag, ...);
|
EXTERN int open(const char *path, int oflag, ...);
|
||||||
EXTERN DIR *opendir(const char *path);
|
|
||||||
EXTERN int read(int fd, void *buf, unsigned int nbytes);
|
EXTERN int read(int fd, void *buf, unsigned int nbytes);
|
||||||
EXTERN struct _dirent *readdir(FAR DIR *dirp);
|
|
||||||
EXTERN int readdir_r(FAR DIR *dirp, struct dirent *entry, FAR struct dirent **result);
|
|
||||||
EXTERN void rewinddir(FAR DIR *dirp);
|
|
||||||
EXTERN int rmdir(const char *path);
|
EXTERN int rmdir(const char *path);
|
||||||
EXTERN void seekdir(FAR DIR *dirp, int loc);
|
|
||||||
EXTERN int stat(const char *path, FAR struct stat *buf);
|
EXTERN int stat(const char *path, FAR struct stat *buf);
|
||||||
EXTERN int statfs(const char *path, FAR struct statfs *buf);
|
EXTERN int statfs(const char *path, FAR struct statfs *buf);
|
||||||
EXTERN int telldir(FAR DIR *dirp);
|
|
||||||
EXTERN int unlink(const char *path);
|
EXTERN int unlink(const char *path);
|
||||||
EXTERN int write(int fd, const void *buf, unsigned int nbytes);
|
EXTERN int write(int fd, const void *buf, unsigned int nbytes);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user