mirror of
https://github.com/apache/nuttx.git
synced 2026-08-28 21:00:44 +00:00
fs/hostfs: add link, symlink, readlink and lstat support
Implemented link(), symlink(), readlink() and lstat() in hostfs. Signed-off-by: zhengyu16 <zhengyu16@xiaomi.com>
This commit is contained in:
parent
c7a78c01c1
commit
86193c95ca
9 changed files with 568 additions and 24 deletions
|
|
@ -370,3 +370,31 @@ int host_chstat(const char *path, const struct stat *buf, int flags)
|
|||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FS_LINKS
|
||||
int host_link(const char *path1, const char *path2)
|
||||
{
|
||||
/* ARM semihosting doesn't support hard links */
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int host_symlink(const char *target, const char *linkpath)
|
||||
{
|
||||
/* ARM semihosting doesn't support symbolic links */
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
ssize_t host_readlink(const char *path, char *buf, size_t bufsize)
|
||||
{
|
||||
/* ARM semihosting doesn't support symbolic links */
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int host_lstat(const char *path, struct stat *buf)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_FS_LINKS */
|
||||
|
|
|
|||
|
|
@ -370,3 +370,25 @@ int host_chstat(const char *path, const struct stat *buf, int flags)
|
|||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FS_LINKS
|
||||
int host_link(const char *path1, const char *path2)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int host_symlink(const char *target, const char *linkpath)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
ssize_t host_readlink(const char *path, char *buf, size_t bufsize)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int host_lstat(const char *path, struct stat *buf)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_FS_LINKS */
|
||||
|
|
|
|||
|
|
@ -368,3 +368,25 @@ int host_chstat(const char *path, const struct stat *buf, int flags)
|
|||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FS_LINKS
|
||||
int host_link(const char *path1, const char *path2)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int host_symlink(const char *target, const char *linkpath)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
ssize_t host_readlink(const char *path, char *buf, size_t bufsize)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int host_lstat(const char *path, struct stat *buf)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_FS_LINKS */
|
||||
|
|
|
|||
|
|
@ -75,9 +75,11 @@ NXSYMBOLS(getpid)
|
|||
NXSYMBOLS(getsockopt)
|
||||
NXSYMBOLS(if_nametoindex)
|
||||
NXSYMBOLS(ioctl)
|
||||
NXSYMBOLS(link)
|
||||
NXSYMBOLS(listen)
|
||||
NXSYMBOLS(longjmp)
|
||||
NXSYMBOLS(lseek)
|
||||
NXSYMBOLS(lstat)
|
||||
NXSYMBOLS(malloc)
|
||||
NXSYMBOLS(malloc_size)
|
||||
NXSYMBOLS(malloc_usable_size)
|
||||
|
|
@ -154,6 +156,7 @@ NXSYMBOLS(strchr)
|
|||
NXSYMBOLS(strerror)
|
||||
NXSYMBOLS(strlen)
|
||||
NXSYMBOLS(strtol)
|
||||
NXSYMBOLS(symlink)
|
||||
NXSYMBOLS(sysconf)
|
||||
NXSYMBOLS(syslog)
|
||||
NXSYMBOLS(system)
|
||||
|
|
|
|||
|
|
@ -820,3 +820,74 @@ int host_chstat(const char *path, const struct nuttx_stat_s *buf, int flags)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_link
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_FS_LINKS
|
||||
int host_link(const char *path1, const char *path2)
|
||||
{
|
||||
int ret = link(path1, path2);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -errno;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_symlink
|
||||
****************************************************************************/
|
||||
|
||||
int host_symlink(const char *target, const char *linkpath)
|
||||
{
|
||||
int ret = symlink(target, linkpath);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -errno;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_readlink
|
||||
****************************************************************************/
|
||||
|
||||
nuttx_ssize_t host_readlink(const char *path, char *buf,
|
||||
nuttx_size_t bufsize)
|
||||
{
|
||||
ssize_t ret = readlink(path, buf, bufsize);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -errno;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_lstat
|
||||
****************************************************************************/
|
||||
|
||||
int host_lstat(const char *path, struct nuttx_stat_s *buf)
|
||||
{
|
||||
struct stat hostbuf;
|
||||
int ret;
|
||||
|
||||
/* Call the host's lstat routine */
|
||||
|
||||
ret = lstat(path, &hostbuf);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -errno;
|
||||
}
|
||||
|
||||
/* Map the return values */
|
||||
|
||||
host_stat_convert(&hostbuf, buf);
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_FS_LINKS */
|
||||
|
|
|
|||
|
|
@ -461,3 +461,42 @@ int host_chstat(const char *path, const struct nuttx_stat_s *buf, int flags)
|
|||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_link
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_FS_LINKS
|
||||
int host_link(const char *path1, const char *path2)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_symlink
|
||||
****************************************************************************/
|
||||
|
||||
int host_symlink(const char *target, const char *linkpath)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_readlink
|
||||
****************************************************************************/
|
||||
|
||||
nuttx_ssize_t host_readlink(const char *path, char *buf,
|
||||
nuttx_size_t bufsize)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_lstat
|
||||
****************************************************************************/
|
||||
|
||||
int host_lstat(const char *path, struct nuttx_stat_s *buf)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_FS_LINKS */
|
||||
|
|
|
|||
|
|
@ -256,3 +256,25 @@ int host_chstat(const char *path, const struct stat *buf, int flags)
|
|||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FS_LINKS
|
||||
int host_link(const char *path1, const char *path2)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int host_symlink(const char *target, const char *linkpath)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
ssize_t host_readlink(const char *path, char *buf, size_t bufsize)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int host_lstat(const char *path, struct stat *buf)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_FS_LINKS */
|
||||
|
|
|
|||
|
|
@ -117,6 +117,21 @@ static int hostfs_chstat(FAR struct inode *mountpt,
|
|||
FAR const char *relpath,
|
||||
FAR const struct stat *buf, int flags);
|
||||
|
||||
#ifdef CONFIG_FS_LINKS
|
||||
static int hostfs_link(FAR struct inode *mountpt,
|
||||
FAR const char *relpath1,
|
||||
FAR const char *relpath2);
|
||||
static int hostfs_symlink(FAR struct inode *mountpt,
|
||||
FAR const char *path1,
|
||||
FAR const char *relpath2);
|
||||
static ssize_t hostfs_readlink(FAR struct inode *mountpt,
|
||||
FAR const char *relpath,
|
||||
FAR char *buf, size_t bufsize);
|
||||
static int hostfs_lstat(FAR struct inode *mountpt,
|
||||
FAR const char *relpath,
|
||||
FAR struct stat *buf);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
|
@ -160,6 +175,15 @@ const struct mountpt_operations g_hostfs_operations =
|
|||
hostfs_rename, /* rename */
|
||||
hostfs_stat, /* stat */
|
||||
hostfs_chstat, /* chstat */
|
||||
NULL, /* syncfs */
|
||||
NULL, /* ioctldir */
|
||||
NULL, /* permission */
|
||||
#ifdef CONFIG_FS_LINKS
|
||||
hostfs_link, /* link */
|
||||
hostfs_symlink, /* symlink */
|
||||
hostfs_readlink, /* readlink */
|
||||
hostfs_lstat, /* lstat */
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -237,7 +261,7 @@ static int hostfs_open(FAR struct file *filep, FAR const char *relpath,
|
|||
FAR struct inode *inode;
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
FAR struct hostfs_ofile_s *hf;
|
||||
char path[HOSTFS_MAX_PATH];
|
||||
FAR char *path;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
|
|
@ -254,12 +278,18 @@ static int hostfs_open(FAR struct file *filep, FAR const char *relpath,
|
|||
|
||||
DEBUGASSERT(fs != NULL);
|
||||
|
||||
path = lib_get_tempbuffer(HOSTFS_MAX_PATH);
|
||||
if (path == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Take the lock */
|
||||
|
||||
ret = nxmutex_lock(&fs->fs_lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_path;
|
||||
}
|
||||
|
||||
/* Allocate memory for the open file */
|
||||
|
|
@ -274,7 +304,7 @@ static int hostfs_open(FAR struct file *filep, FAR const char *relpath,
|
|||
|
||||
/* Append to the host's root directory */
|
||||
|
||||
hostfs_mkpath(fs, relpath, path, sizeof(path));
|
||||
hostfs_mkpath(fs, relpath, path, HOSTFS_MAX_PATH);
|
||||
|
||||
/* Try to open the file in the host file system */
|
||||
|
||||
|
|
@ -328,6 +358,10 @@ errout_with_buffer:
|
|||
|
||||
errout_with_lock:
|
||||
nxmutex_unlock(&fs->fs_lock);
|
||||
|
||||
errout_with_path:
|
||||
lib_put_tempbuffer(path);
|
||||
|
||||
if (ret == -EINVAL)
|
||||
{
|
||||
ret = -EIO;
|
||||
|
|
@ -839,20 +873,27 @@ static int hostfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
|||
{
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
FAR struct hostfs_dir_s *hdir;
|
||||
char path[HOSTFS_MAX_PATH];
|
||||
FAR char *path;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL);
|
||||
|
||||
path = lib_get_tempbuffer(HOSTFS_MAX_PATH);
|
||||
if (path == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Recover our private data from the inode instance */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
hdir = fs_heap_zalloc(sizeof(struct hostfs_dir_s));
|
||||
if (hdir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_path;
|
||||
}
|
||||
|
||||
/* Take the lock */
|
||||
|
|
@ -865,7 +906,7 @@ static int hostfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
|||
|
||||
/* Append to the host's root directory */
|
||||
|
||||
hostfs_mkpath(fs, relpath, path, sizeof(path));
|
||||
hostfs_mkpath(fs, relpath, path, HOSTFS_MAX_PATH);
|
||||
|
||||
/* Call the host's opendir function */
|
||||
|
||||
|
|
@ -878,6 +919,7 @@ static int hostfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
|||
|
||||
*dir = (FAR struct fs_dirent_s *)hdir;
|
||||
nxmutex_unlock(&fs->fs_lock);
|
||||
lib_put_tempbuffer(path);
|
||||
return OK;
|
||||
|
||||
errout_with_lock:
|
||||
|
|
@ -885,6 +927,9 @@ errout_with_lock:
|
|||
|
||||
errout_with_hdir:
|
||||
fs_heap_free(hdir);
|
||||
|
||||
errout_with_path:
|
||||
lib_put_tempbuffer(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1204,13 +1249,19 @@ static int hostfs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf)
|
|||
static int hostfs_unlink(FAR struct inode *mountpt, FAR const char *relpath)
|
||||
{
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
char path[HOSTFS_MAX_PATH];
|
||||
FAR char *path;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(mountpt && mountpt->i_private);
|
||||
|
||||
path = lib_get_tempbuffer(HOSTFS_MAX_PATH);
|
||||
if (path == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Get the mountpoint private data from the inode structure */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
|
|
@ -1218,18 +1269,21 @@ static int hostfs_unlink(FAR struct inode *mountpt, FAR const char *relpath)
|
|||
ret = nxmutex_lock(&fs->fs_lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_path;
|
||||
}
|
||||
|
||||
/* Append to the host's root directory */
|
||||
|
||||
hostfs_mkpath(fs, relpath, path, sizeof(path));
|
||||
hostfs_mkpath(fs, relpath, path, HOSTFS_MAX_PATH);
|
||||
|
||||
/* Call the host fs to perform the unlink */
|
||||
|
||||
ret = host_unlink(path);
|
||||
|
||||
nxmutex_unlock(&fs->fs_lock);
|
||||
|
||||
errout_with_path:
|
||||
lib_put_tempbuffer(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1244,13 +1298,19 @@ static int hostfs_mkdir(FAR struct inode *mountpt, FAR const char *relpath,
|
|||
mode_t mode)
|
||||
{
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
char path[HOSTFS_MAX_PATH];
|
||||
FAR char *path;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(mountpt && mountpt->i_private);
|
||||
|
||||
path = lib_get_tempbuffer(HOSTFS_MAX_PATH);
|
||||
if (path == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Get the mountpoint private data from the inode structure */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
|
|
@ -1258,18 +1318,21 @@ static int hostfs_mkdir(FAR struct inode *mountpt, FAR const char *relpath,
|
|||
ret = nxmutex_lock(&fs->fs_lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_path;
|
||||
}
|
||||
|
||||
/* Append to the host's root directory */
|
||||
|
||||
hostfs_mkpath(fs, relpath, path, sizeof(path));
|
||||
hostfs_mkpath(fs, relpath, path, HOSTFS_MAX_PATH);
|
||||
|
||||
/* Call the host FS to do the mkdir */
|
||||
|
||||
ret = host_mkdir(path, mode);
|
||||
|
||||
nxmutex_unlock(&fs->fs_lock);
|
||||
|
||||
errout_with_path:
|
||||
lib_put_tempbuffer(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1283,13 +1346,19 @@ static int hostfs_mkdir(FAR struct inode *mountpt, FAR const char *relpath,
|
|||
int hostfs_rmdir(FAR struct inode *mountpt, FAR const char *relpath)
|
||||
{
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
char path[HOSTFS_MAX_PATH];
|
||||
FAR char *path;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(mountpt && mountpt->i_private);
|
||||
|
||||
path = lib_get_tempbuffer(HOSTFS_MAX_PATH);
|
||||
if (path == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Get the mountpoint private data from the inode structure */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
|
|
@ -1299,18 +1368,21 @@ int hostfs_rmdir(FAR struct inode *mountpt, FAR const char *relpath)
|
|||
ret = nxmutex_lock(&fs->fs_lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_path;
|
||||
}
|
||||
|
||||
/* Append to the host's root directory */
|
||||
|
||||
hostfs_mkpath(fs, relpath, path, sizeof(path));
|
||||
hostfs_mkpath(fs, relpath, path, HOSTFS_MAX_PATH);
|
||||
|
||||
/* Call the host FS to do the mkdir */
|
||||
|
||||
ret = host_rmdir(path);
|
||||
|
||||
nxmutex_unlock(&fs->fs_lock);
|
||||
|
||||
errout_with_path:
|
||||
lib_put_tempbuffer(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1325,14 +1397,27 @@ int hostfs_rename(FAR struct inode *mountpt, FAR const char *oldrelpath,
|
|||
FAR const char *newrelpath)
|
||||
{
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
char oldpath[HOSTFS_MAX_PATH];
|
||||
char newpath[HOSTFS_MAX_PATH];
|
||||
FAR char *oldpath;
|
||||
FAR char *newpath;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(mountpt && mountpt->i_private);
|
||||
|
||||
oldpath = lib_get_tempbuffer(HOSTFS_MAX_PATH);
|
||||
if (oldpath == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
newpath = lib_get_tempbuffer(HOSTFS_MAX_PATH);
|
||||
if (newpath == NULL)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_oldpath;
|
||||
}
|
||||
|
||||
/* Get the mountpoint private data from the inode structure */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
|
|
@ -1340,7 +1425,7 @@ int hostfs_rename(FAR struct inode *mountpt, FAR const char *oldrelpath,
|
|||
ret = nxmutex_lock(&fs->fs_lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_newpath;
|
||||
}
|
||||
|
||||
/* Append to the host's root directory */
|
||||
|
|
@ -1355,6 +1440,12 @@ int hostfs_rename(FAR struct inode *mountpt, FAR const char *oldrelpath,
|
|||
ret = host_rename(oldpath, newpath);
|
||||
|
||||
nxmutex_unlock(&fs->fs_lock);
|
||||
|
||||
errout_with_newpath:
|
||||
lib_put_tempbuffer(newpath);
|
||||
|
||||
errout_with_oldpath:
|
||||
lib_put_tempbuffer(oldpath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1369,13 +1460,19 @@ static int hostfs_stat(FAR struct inode *mountpt, FAR const char *relpath,
|
|||
FAR struct stat *buf)
|
||||
{
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
char path[HOSTFS_MAX_PATH];
|
||||
FAR char *path;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(mountpt && mountpt->i_private);
|
||||
|
||||
path = lib_get_tempbuffer(HOSTFS_MAX_PATH);
|
||||
if (path == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Get the mountpoint private data from the inode structure */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
|
|
@ -1383,18 +1480,21 @@ static int hostfs_stat(FAR struct inode *mountpt, FAR const char *relpath,
|
|||
ret = nxmutex_lock(&fs->fs_lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_path;
|
||||
}
|
||||
|
||||
/* Append to the host's root directory */
|
||||
|
||||
hostfs_mkpath(fs, relpath, path, sizeof(path));
|
||||
hostfs_mkpath(fs, relpath, path, HOSTFS_MAX_PATH);
|
||||
|
||||
/* Call the host FS to do the stat operation */
|
||||
|
||||
ret = host_stat(path, buf);
|
||||
|
||||
nxmutex_unlock(&fs->fs_lock);
|
||||
|
||||
errout_with_path:
|
||||
lib_put_tempbuffer(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1409,13 +1509,19 @@ static int hostfs_chstat(FAR struct inode *mountpt, FAR const char *relpath,
|
|||
FAR const struct stat *buf, int flags)
|
||||
{
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
char path[HOSTFS_MAX_PATH];
|
||||
FAR char *path;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(mountpt && mountpt->i_private);
|
||||
|
||||
path = lib_get_tempbuffer(HOSTFS_MAX_PATH);
|
||||
if (path == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Get the mountpoint private data from the inode structure */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
|
|
@ -1423,21 +1529,239 @@ static int hostfs_chstat(FAR struct inode *mountpt, FAR const char *relpath,
|
|||
ret = nxmutex_lock(&fs->fs_lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
goto errout_with_path;
|
||||
}
|
||||
|
||||
/* Append to the host's root directory */
|
||||
|
||||
hostfs_mkpath(fs, relpath, path, sizeof(path));
|
||||
hostfs_mkpath(fs, relpath, path, HOSTFS_MAX_PATH);
|
||||
|
||||
/* Call the host FS to do the chstat operation */
|
||||
|
||||
ret = host_chstat(path, buf, flags);
|
||||
|
||||
nxmutex_unlock(&fs->fs_lock);
|
||||
|
||||
errout_with_path:
|
||||
lib_put_tempbuffer(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FS_LINKS
|
||||
/****************************************************************************
|
||||
* Name: hostfs_link
|
||||
*
|
||||
* Description: Create a hard link
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int hostfs_link(FAR struct inode *mountpt, FAR const char *relpath1,
|
||||
FAR const char *relpath2)
|
||||
{
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
FAR char *path1;
|
||||
FAR char *path2;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(mountpt && mountpt->i_private);
|
||||
|
||||
path1 = lib_get_tempbuffer(HOSTFS_MAX_PATH);
|
||||
if (path1 == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
path2 = lib_get_tempbuffer(HOSTFS_MAX_PATH);
|
||||
if (path2 == NULL)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_path1;
|
||||
}
|
||||
|
||||
/* Get the mountpoint private data from the inode structure */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
|
||||
ret = nxmutex_lock(&fs->fs_lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_path2;
|
||||
}
|
||||
|
||||
/* Append to the host's root directory */
|
||||
|
||||
hostfs_mkpath(fs, relpath1, path1, HOSTFS_MAX_PATH);
|
||||
hostfs_mkpath(fs, relpath2, path2, HOSTFS_MAX_PATH);
|
||||
|
||||
/* Call the host FS to create the hard link */
|
||||
|
||||
ret = host_link(path1, path2);
|
||||
|
||||
nxmutex_unlock(&fs->fs_lock);
|
||||
|
||||
errout_with_path2:
|
||||
lib_put_tempbuffer(path2);
|
||||
|
||||
errout_with_path1:
|
||||
lib_put_tempbuffer(path1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hostfs_symlink
|
||||
*
|
||||
* Description: Create a symbolic link
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int hostfs_symlink(FAR struct inode *mountpt,
|
||||
FAR const char *path1,
|
||||
FAR const char *relpath2)
|
||||
{
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
FAR char *fullpath2;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(mountpt && mountpt->i_private);
|
||||
|
||||
fullpath2 = lib_get_tempbuffer(HOSTFS_MAX_PATH);
|
||||
if (fullpath2 == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Get the mountpoint private data from the inode structure */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
|
||||
ret = nxmutex_lock(&fs->fs_lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_path;
|
||||
}
|
||||
|
||||
/* Build the full path for the link location (relpath2)
|
||||
* The target (path1) is used as-is, allowing relative or absolute paths
|
||||
*/
|
||||
|
||||
hostfs_mkpath(fs, relpath2, fullpath2, HOSTFS_MAX_PATH);
|
||||
|
||||
/* Call the host FS to create the symbolic link */
|
||||
|
||||
ret = host_symlink(path1, fullpath2);
|
||||
|
||||
nxmutex_unlock(&fs->fs_lock);
|
||||
|
||||
errout_with_path:
|
||||
lib_put_tempbuffer(fullpath2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hostfs_readlink
|
||||
*
|
||||
* Description: Read the target of a symbolic link
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t hostfs_readlink(FAR struct inode *mountpt,
|
||||
FAR const char *relpath,
|
||||
FAR char *buf, size_t bufsize)
|
||||
{
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
FAR char *path;
|
||||
ssize_t ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(mountpt && mountpt->i_private);
|
||||
|
||||
path = lib_get_tempbuffer(HOSTFS_MAX_PATH);
|
||||
if (path == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Get the mountpoint private data from the inode structure */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
|
||||
ret = nxmutex_lock(&fs->fs_lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_path;
|
||||
}
|
||||
|
||||
/* Append to the host's root directory */
|
||||
|
||||
hostfs_mkpath(fs, relpath, path, HOSTFS_MAX_PATH);
|
||||
|
||||
/* Call the host FS to read the symbolic link */
|
||||
|
||||
ret = host_readlink(path, buf, bufsize);
|
||||
|
||||
nxmutex_unlock(&fs->fs_lock);
|
||||
|
||||
errout_with_path:
|
||||
lib_put_tempbuffer(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hostfs_lstat
|
||||
*
|
||||
* Description: Return information about a file or directory (don't follow
|
||||
* symbolic links)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int hostfs_lstat(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct stat *buf)
|
||||
{
|
||||
FAR struct hostfs_mountpt_s *fs;
|
||||
FAR char *path;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(mountpt && mountpt->i_private);
|
||||
|
||||
path = lib_get_tempbuffer(HOSTFS_MAX_PATH);
|
||||
if (path == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Get the mountpoint private data from the inode structure */
|
||||
|
||||
fs = mountpt->i_private;
|
||||
|
||||
ret = nxmutex_lock(&fs->fs_lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_path;
|
||||
}
|
||||
|
||||
/* Append to the host's root directory */
|
||||
|
||||
hostfs_mkpath(fs, relpath, path, HOSTFS_MAX_PATH);
|
||||
|
||||
/* Call the host FS to do the lstat operation */
|
||||
|
||||
ret = host_lstat(path, buf);
|
||||
|
||||
nxmutex_unlock(&fs->fs_lock);
|
||||
|
||||
errout_with_path:
|
||||
lib_put_tempbuffer(path);
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_FS_LINKS */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -256,6 +256,13 @@ int host_rename(const char *oldpath, const char *newpath);
|
|||
int host_stat(const char *path, struct nuttx_stat_s *buf);
|
||||
int host_chstat(const char *path,
|
||||
const struct nuttx_stat_s *buf, int flags);
|
||||
#ifdef CONFIG_FS_LINKS
|
||||
int host_link(const char *path1, const char *path2);
|
||||
int host_symlink(const char *target, const char *linkpath);
|
||||
nuttx_ssize_t host_readlink(const char *path, char *buf,
|
||||
nuttx_size_t bufsize);
|
||||
int host_lstat(const char *path, struct nuttx_stat_s *buf);
|
||||
#endif
|
||||
#else
|
||||
int host_open(const char *pathname, int flags, int mode);
|
||||
int host_close(int fd);
|
||||
|
|
@ -280,6 +287,12 @@ int host_rename(const char *oldpath, const char *newpath);
|
|||
int host_stat(const char *path, struct stat *buf);
|
||||
int host_chstat(const char *path,
|
||||
const struct stat *buf, int flags);
|
||||
#ifdef CONFIG_FS_LINKS
|
||||
int host_link(const char *path1, const char *path2);
|
||||
int host_symlink(const char *target, const char *linkpath);
|
||||
ssize_t host_readlink(const char *path, char *buf, size_t bufsize);
|
||||
int host_lstat(const char *path, struct stat *buf);
|
||||
#endif
|
||||
#endif /* __SIM__ */
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_FS_HOSTFS_H */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue