Soft links: Initial, incompete implementation
This commit is contained in:
parent
74189d84e2
commit
92305e400a
7 changed files with 239 additions and 13 deletions
13
fs/Kconfig
13
fs/Kconfig
|
@ -40,6 +40,19 @@ config DISABLE_PSEUDOFS_OPERATIONS
|
|||
However, in practical embedded system, they are seldom needed and
|
||||
you can save a little FLASH space by disabling the capability.
|
||||
|
||||
config PSEUDOFS_SOFTLINKS
|
||||
bool "Pseudo-filesystem soft links"
|
||||
default y if DEFAULT_SMALL
|
||||
default n if !DEFAULT_SMALL
|
||||
depends on !DISABLE_PSEUDOFS_OPERATIONS
|
||||
---help---
|
||||
Enable support for soft links in the pseudeo file system. Soft
|
||||
links are not supported within mounted volumes by any NuttX file
|
||||
system. However, if this option is selected, then soft links
|
||||
may be add in the pseudo file system. This might be useful, for
|
||||
to link a directory in the pseudo-file system, such as /bin, to
|
||||
to a directory in a mounted volume, say /mnt/sdcard/bin.
|
||||
|
||||
config FS_READABLE
|
||||
bool
|
||||
default n
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* fs/inode/fs_inode.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011-2012, 2016 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2011-2012, 2016-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <semaphore.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
@ -345,6 +346,7 @@ FAR struct inode *inode_search(FAR const char **path,
|
|||
{
|
||||
*relpath = name;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
@ -401,8 +403,29 @@ void inode_free(FAR struct inode *node)
|
|||
|
||||
if (node != NULL)
|
||||
{
|
||||
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
||||
/* Symbol links should never have peers or children */
|
||||
|
||||
DEBUGASSERT(!INODE_IS_SOFTLINK(node)) ||
|
||||
(node->i_peer == NULL && node->i_child == NULL)
|
||||
#endif
|
||||
|
||||
/* Free all peers and children of this i_node */
|
||||
|
||||
inode_free(node->i_peer);
|
||||
inode_free(node->i_child);
|
||||
|
||||
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
||||
/* If the inode is a symbolic link, the free the path to the linked
|
||||
* entity.
|
||||
*/
|
||||
|
||||
if (INODE_IS_SOFTLINK(node) && inode->u.i_link != NULL)
|
||||
{
|
||||
kmm_free(node->u.i_link);
|
||||
}
|
||||
#endif
|
||||
|
||||
kmm_free(node);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
############################################################################
|
||||
# fs/vfs/Make.defs
|
||||
#
|
||||
# Copyright (C) 2014-2015 Gregory Nutt. All rights reserved.
|
||||
# Copyright (C) 2014-2015, 2017 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
@ -43,7 +43,11 @@ ifneq ($(CONFIG_NSOCKET_DESCRIPTORS),0)
|
|||
|
||||
CSRCS += fs_close.c fs_read.c fs_write.c fs_ioctl.c
|
||||
|
||||
# Support for network access using streams
|
||||
ifneq ($(CONFIG_PSEUDOFS_SOFTLINKS),0)
|
||||
CSRCS += fs_softlink.c
|
||||
endif
|
||||
|
||||
# Stream support
|
||||
|
||||
ifneq ($(CONFIG_NFILE_STREAMS),0)
|
||||
CSRCS += fs_fdopen.c
|
||||
|
@ -86,6 +90,10 @@ endif
|
|||
|
||||
CSRCS += fs_pread.c fs_pwrite.c
|
||||
|
||||
ifneq ($(CONFIG_PSEUDOFS_SOFTLINKS),0)
|
||||
CSRCS += fs_softlink.c
|
||||
endif
|
||||
|
||||
# Stream support
|
||||
|
||||
ifneq ($(CONFIG_NFILE_STREAMS),0)
|
||||
|
|
|
@ -84,8 +84,9 @@ int rmdir(FAR const char *pathname)
|
|||
const char *relpath = NULL;
|
||||
int errcode;
|
||||
|
||||
/* Get an inode for this file. inode_find() automatically increments the
|
||||
* reference count on the inode if one is found.
|
||||
/* Get an inode for the directory (or for the mountpoint containing the
|
||||
* directory). inode_find() automatically increments the reference count
|
||||
* on the inode if one is found.
|
||||
*/
|
||||
|
||||
inode = inode_find(pathname, &relpath);
|
||||
|
|
169
fs/vfs/fs_softlink.c
Normal file
169
fs/vfs/fs_softlink.c
Normal file
|
@ -0,0 +1,169 @@
|
|||
/****************************************************************************
|
||||
* fs/vfs/fs_softlink.c
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* 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 NuttX 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 <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include "inode/inode.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: link
|
||||
*
|
||||
* Description:
|
||||
* The link() function will create a new link (directory entry) for the
|
||||
* existing file, path1. This implementation is simplied for use with
|
||||
* NuttX in these ways:
|
||||
*
|
||||
* - Links may be created only within the NuttX top-level, pseudo file
|
||||
* system. No file system currently supported by NuttX provides
|
||||
* symbolic links.
|
||||
* - For the same reason, only soft links are implemented.
|
||||
* - File privileges are ignored.
|
||||
* - c_time is not updated.
|
||||
*
|
||||
* Input Parameters:
|
||||
* path1 - Points to a pathname naming an existing file.
|
||||
* path2 - Points to a pathname naming the new directory entry to be created.
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, zero (OK) is returned. Otherwise, -1 (ERROR) is returned
|
||||
* the the errno variable is set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int link(FAR const char *path1, FAR const char *path2)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
int errcode;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(path1 != NULL && path2 != NULL && *path2 != '\0');
|
||||
|
||||
/* Check that no inode exists at the 'path2' and that the path up to 'path2'
|
||||
* does not lie on a mounted volume.
|
||||
*/
|
||||
|
||||
inode = inode_find(pathname, NULL);
|
||||
if (inode != NULL)
|
||||
{
|
||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||
/* Check if the inode is a mountpoint. */
|
||||
|
||||
if (INODE_IS_MOUNTPT(inode))
|
||||
{
|
||||
/* Symbol links within the mounted volume are not supported */
|
||||
|
||||
errcode = ENOSYS;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* A node already exists in the pseudofs at 'path2' */
|
||||
|
||||
errorcode = EEXIST;
|
||||
}
|
||||
|
||||
goto errout_with_inode;
|
||||
}
|
||||
|
||||
/* No inode exists that contains this path. Create a new inode in the
|
||||
* pseudo-filesystem at this location.
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
/* Copy path2 */
|
||||
|
||||
FAR char newpath2 = strdup(path2);
|
||||
if (newpath2 == NULL)
|
||||
{
|
||||
errcode = ENOMEM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Create an inode in the pseudo-filesystem at this path.
|
||||
* NOTE that the new inode will be created with a reference
|
||||
* count of zero.
|
||||
*/
|
||||
|
||||
inode_semtake();
|
||||
ret = inode_reserve(pathname, &inode);
|
||||
inode_semgive();
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
kmm_free(newpath2)
|
||||
errcode = -ret;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Initialize the inode */
|
||||
|
||||
INODE_SET_SOFTLINK(inode);
|
||||
inode->u.i_link = newpath2;
|
||||
inode->i_crefs = 1;
|
||||
}
|
||||
|
||||
/* Symbolic link successfully created */
|
||||
|
||||
return OK;
|
||||
|
||||
errout_with_inode:
|
||||
inode_release(inode);
|
||||
errout:
|
||||
set_errno(errcode);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PSEUDOFS_SOFTLINKS */
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* include/nuttx/fs/fs.h
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011-2013, 2015-2016 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2011-2013, 2015-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -66,12 +66,17 @@
|
|||
#define __FS_FLAG_EOF (1 << 0) /* EOF detected by a read operation */
|
||||
#define __FS_FLAG_ERROR (1 << 1) /* Error detected by any operation */
|
||||
|
||||
/* Inode i_flag values */
|
||||
/* Inode i_flag values:
|
||||
*
|
||||
* Bit 0-3: Inode type (Bit 4 indicates internal OS types)
|
||||
* Bit 4: Set if inode has been unlinked and is pending removal.
|
||||
*/
|
||||
|
||||
#define FSNODEFLAG_TYPE_MASK 0x00000007 /* Isolates type field */
|
||||
#define FSNODEFLAG_TYPE_DRIVER 0x00000000 /* Character driver */
|
||||
#define FSNODEFLAG_TYPE_BLOCK 0x00000001 /* Block driver */
|
||||
#define FSNODEFLAG_TYPE_MOUNTPT 0x00000002 /* Mount point */
|
||||
#define FSNODEFLAG_TYPE_SOFTLINK 0x00000003 /* Soft link */
|
||||
#define FSNODEFLAG_TYPE_SPECIAL 0x00000004 /* Special OS type */
|
||||
#define FSNODEFLAG_TYPE_NAMEDSEM 0x00000004 /* Named semaphore */
|
||||
#define FSNODEFLAG_TYPE_MQUEUE 0x00000005 /* Message Queue */
|
||||
|
@ -86,6 +91,7 @@
|
|||
#define INODE_IS_DRIVER(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_DRIVER)
|
||||
#define INODE_IS_BLOCK(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_BLOCK)
|
||||
#define INODE_IS_MOUNTPT(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_MOUNTPT)
|
||||
#define INODE_IS_SOFTLINK(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_SOFTLINK)
|
||||
#define INODE_IS_NAMEDSEM(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_NAMEDSEM)
|
||||
#define INODE_IS_MQUEUE(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_MQUEUE)
|
||||
#define INODE_IS_SHM(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_SHM)
|
||||
|
@ -101,6 +107,7 @@
|
|||
#define INODE_SET_DRIVER(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_DRIVER)
|
||||
#define INODE_SET_BLOCK(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_BLOCK)
|
||||
#define INODE_SET_MOUNTPT(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_MOUNTPT)
|
||||
#define (i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_SOFTLINK)
|
||||
#define INODE_SET_NAMEDSEM(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_NAMEDSEM)
|
||||
#define INODE_SET_MQUEUE(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_MQUEUE)
|
||||
#define INODE_SET_SHM(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_SHM)
|
||||
|
@ -320,6 +327,9 @@ union inode_ops_u
|
|||
#ifndef CONFIG_DISABLE_MQUEUE
|
||||
FAR struct mqueue_inode_s *i_mqueue; /* POSIX message queue */
|
||||
#endif
|
||||
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
||||
FAR char *i_link; /* Full path to link */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* This structure represents one inode in the Nuttx pseudo-file system */
|
||||
|
@ -337,6 +347,7 @@ struct inode
|
|||
FAR void *i_private; /* Per inode driver private data */
|
||||
char i_name[1]; /* Name of inode (variable) */
|
||||
};
|
||||
|
||||
#define FSNODE_SIZE(n) (sizeof(struct inode) + (n))
|
||||
|
||||
/* This is the underlying representation of an open file. A file
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* include/unistd.h
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2013-2014, 2016 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2013-2014, 2016-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -190,6 +190,7 @@ FAR char *getcwd(FAR char *buf, size_t size);
|
|||
int access(FAR const char *path, int amode);
|
||||
int rmdir(FAR const char *pathname);
|
||||
int unlink(FAR const char *pathname);
|
||||
int link(FAR const char *path1, FAR const char *path2);
|
||||
|
||||
/* Execution of programs from files */
|
||||
|
||||
|
|
Loading…
Reference in a new issue