forked from nuttx/nuttx-update
fs/dir: support fchdir and dirfd
Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
parent
fe17f747a7
commit
4dbf4555eb
8 changed files with 182 additions and 4 deletions
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
|
||||
#include "inode/inode.h"
|
||||
|
||||
|
@ -51,10 +52,12 @@ struct fs_pseudodir_s
|
|||
* Private Functions Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int dir_open(FAR struct file *filep);
|
||||
static int dir_close(FAR struct file *filep);
|
||||
static ssize_t dir_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t buflen);
|
||||
static off_t dir_seek(FAR struct file *filep, off_t offset, int whence);
|
||||
static int dir_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
|
@ -62,12 +65,12 @@ static off_t dir_seek(FAR struct file *filep, off_t offset, int whence);
|
|||
|
||||
static const struct file_operations g_dir_fileops =
|
||||
{
|
||||
NULL, /* open */
|
||||
dir_open, /* open */
|
||||
dir_close, /* close */
|
||||
dir_read, /* read */
|
||||
NULL, /* write */
|
||||
dir_seek, /* seek */
|
||||
NULL, /* ioctl */
|
||||
dir_ioctl, /* ioctl */
|
||||
NULL, /* poll */
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
NULL, /* unlink */
|
||||
|
@ -391,10 +394,18 @@ static int read_pseudodir(FAR struct fs_dirent_s *dir,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int dir_open(FAR struct file *filep)
|
||||
{
|
||||
FAR struct fs_dirent_s *dir = filep->f_priv;
|
||||
|
||||
return dir_allocate(filep, dir->fd_path);
|
||||
}
|
||||
|
||||
static int dir_close(FAR struct file *filep)
|
||||
{
|
||||
FAR struct fs_dirent_s *dir = filep->f_priv;
|
||||
FAR struct inode *inode = dir->fd_root;
|
||||
FAR char *relpath = dir->fd_path;
|
||||
int ret = 0;
|
||||
|
||||
/* This is the 'root' inode of the directory. This means different
|
||||
|
@ -440,6 +451,7 @@ static int dir_close(FAR struct file *filep)
|
|||
/* Release our references on the contained 'root' inode */
|
||||
|
||||
inode_release(inode);
|
||||
kmm_free(relpath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -533,6 +545,20 @@ static off_t dir_seek(FAR struct file *filep, off_t offset, int whence)
|
|||
return pos;
|
||||
}
|
||||
|
||||
static int dir_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
FAR struct fs_dirent_s *dir = filep->f_priv;
|
||||
int ret = -ENOTTY;
|
||||
|
||||
if (cmd == FIOC_FILEPATH)
|
||||
{
|
||||
strcpy((FAR char *)(uintptr_t)arg, dir->fd_path);
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -574,6 +600,7 @@ int dir_allocate(FAR struct file *filep, FAR const char *relpath)
|
|||
}
|
||||
}
|
||||
|
||||
dir->fd_path = strdup(relpath);
|
||||
filep->f_inode = &g_dir_inode;
|
||||
filep->f_priv = dir;
|
||||
inode_addref(&g_dir_inode);
|
||||
|
|
|
@ -154,6 +154,8 @@ int scandir(FAR const char *path, FAR struct dirent ***namelist,
|
|||
int alphasort(FAR const struct dirent **a,
|
||||
FAR const struct dirent **b);
|
||||
|
||||
int dirfd(FAR DIR *dirp);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
@ -191,6 +191,10 @@ struct fs_dirent_s
|
|||
*/
|
||||
|
||||
FAR struct inode *fd_root;
|
||||
|
||||
/* The path name of current directory for FIOC_FILEPATH */
|
||||
|
||||
FAR char *fd_path;
|
||||
};
|
||||
|
||||
/* This structure is provided by devices when they are registered with the
|
||||
|
|
|
@ -362,6 +362,7 @@ unsigned int alarm(unsigned int seconds);
|
|||
/* Working directory operations */
|
||||
|
||||
int chdir(FAR const char *path);
|
||||
int fchdir(int fd);
|
||||
FAR char *getcwd(FAR char *buf, size_t size);
|
||||
|
||||
/* File path operations */
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
CSRCS += lib_readdirr.c lib_telldir.c lib_alphasort.c lib_scandir.c
|
||||
CSRCS += lib_ftw.c lib_nftw.c lib_opendir.c lib_closedir.c lib_readdir.c
|
||||
CSRCS += lib_rewinddir.c lib_seekdir.c
|
||||
CSRCS += lib_rewinddir.c lib_seekdir.c lib_dirfd.c
|
||||
|
||||
# Add the dirent directory to the build
|
||||
|
||||
|
|
65
libs/libc/dirent/lib_dirfd.c
Normal file
65
libs/libc/dirent/lib_dirfd.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
/****************************************************************************
|
||||
* libs/libc/dirent/lib_dirfd.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: dirfd
|
||||
*
|
||||
* Description:
|
||||
* The dirfd() function returns the file descriptor associated
|
||||
* with the directory stream dirp.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dirp -- An instance of type DIR created by a previous
|
||||
* call to opendir();
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, a nonnegative file descriptor is returned.
|
||||
* On error, -1 is returned, and errno is set to indicate
|
||||
* the cause of the error.
|
||||
*
|
||||
* EINVAL - dirp does not refer to a valid directory stream.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int dirfd(FAR DIR *dirp)
|
||||
{
|
||||
if (dirp != NULL)
|
||||
{
|
||||
return dirp->fd;
|
||||
}
|
||||
|
||||
set_errno(EINVAL);
|
||||
return -1;
|
||||
}
|
|
@ -35,7 +35,7 @@ CSRCS += lib_setuid.c lib_setgid.c lib_getuid.c lib_getgid.c
|
|||
endif
|
||||
|
||||
ifneq ($(CONFIG_DISABLE_ENVIRON),y)
|
||||
CSRCS += lib_chdir.c lib_getcwd.c lib_restoredir.c
|
||||
CSRCS += lib_chdir.c lib_fchdir.c lib_getcwd.c lib_restoredir.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_LIBC_EXECFUNCS),y)
|
||||
|
|
79
libs/libc/unistd/lib_fchdir.c
Normal file
79
libs/libc/unistd/lib_fchdir.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/****************************************************************************
|
||||
* libs/libc/unistd/lib_fchdir.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fchdir
|
||||
*
|
||||
* Description:
|
||||
* The fchdir() function changes the current workint directory of the
|
||||
* calling process to the directory specified in fd.
|
||||
*
|
||||
* The fchdir() function is identical to chdir(); the only difference is
|
||||
* that the directory is given as an open file diescriptor.
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor is the one used internally by the directory
|
||||
* stream.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0(OK) on success; -1(ERROR) on failure with errno set appropriately:
|
||||
*
|
||||
* EACCES
|
||||
* Search permission was denied on the directory open on fd.
|
||||
* EBADF
|
||||
* fd is not a valid file descriptor.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int fchdir(int fd)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
int ret;
|
||||
|
||||
ret = fcntl(fd, F_GETPATH, path);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
return chdir(path);
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_DISABLE_ENVIRON */
|
Loading…
Reference in a new issue