1
0
Fork 0
forked from nuttx/nuttx-update

fs/dir: support fchdir and dirfd

Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
Jiuzhu Dong 2022-08-05 12:04:37 +08:00 committed by Xiang Xiao
parent fe17f747a7
commit 4dbf4555eb
8 changed files with 182 additions and 4 deletions

View file

@ -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);

View file

@ -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)
}

View file

@ -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

View file

@ -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 */

View file

@ -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

View 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;
}

View file

@ -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)

View 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 */