ramfs: add symlink and readlink support
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
This commit is contained in:
parent
1483f45879
commit
ad6c28ac41
61
fs/ramfs.c
61
fs/ramfs.c
|
@ -42,6 +42,7 @@ struct ramfs_inode {
|
|||
struct ramfs_inode *parent;
|
||||
struct ramfs_inode *next;
|
||||
struct ramfs_inode *child;
|
||||
char *symlink;
|
||||
ulong mode;
|
||||
|
||||
struct handle_d *handle;
|
||||
|
@ -176,6 +177,7 @@ static void ramfs_put_inode(struct ramfs_inode *node)
|
|||
data = tmp;
|
||||
}
|
||||
|
||||
free(node->symlink);
|
||||
free(node->name);
|
||||
free(node);
|
||||
}
|
||||
|
@ -212,18 +214,38 @@ static struct ramfs_inode* node_insert(struct ramfs_inode *parent_node, const ch
|
|||
|
||||
/* ---------------------------------------------------------------*/
|
||||
|
||||
static int ramfs_create(struct device_d *dev, const char *pathname, mode_t mode)
|
||||
static int __ramfs_create(struct device_d *dev, const char *pathname,
|
||||
mode_t mode, const char *symlink)
|
||||
{
|
||||
struct ramfs_priv *priv = dev->priv;
|
||||
struct ramfs_inode *node;
|
||||
char *file;
|
||||
char *__symlink = NULL;
|
||||
|
||||
node = rlookup_parent(priv, pathname, &file);
|
||||
if (node) {
|
||||
node_insert(node, file, mode);
|
||||
return 0;
|
||||
if (!node)
|
||||
return -ENOENT;
|
||||
|
||||
if (symlink) {
|
||||
__symlink = strdup(symlink);
|
||||
if (!__symlink)
|
||||
return -ENOMEM;
|
||||
}
|
||||
return -ENOENT;
|
||||
|
||||
node = node_insert(node, file, mode);
|
||||
if (!node) {
|
||||
free(__symlink);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
node->symlink = __symlink;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ramfs_create(struct device_d *dev, const char *pathname, mode_t mode)
|
||||
{
|
||||
return __ramfs_create(dev, pathname, mode, NULL);
|
||||
}
|
||||
|
||||
static int ramfs_unlink(struct device_d *dev, const char *pathname)
|
||||
|
@ -532,12 +554,37 @@ static int ramfs_stat(struct device_d *dev, const char *filename, struct stat *s
|
|||
if (!node)
|
||||
return -ENOENT;
|
||||
|
||||
s->st_size = node->size;
|
||||
s->st_size = node->symlink ? strlen(node->symlink) : node->size;
|
||||
s->st_mode = node->mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ramfs_symlink(struct device_d *dev, const char *pathname,
|
||||
const char *newpath)
|
||||
{
|
||||
mode_t mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
|
||||
return __ramfs_create(dev, newpath, mode, pathname);
|
||||
}
|
||||
|
||||
static int ramfs_readlink(struct device_d *dev, const char *pathname,
|
||||
char *buf, size_t bufsiz)
|
||||
{
|
||||
struct ramfs_priv *priv = dev->priv;
|
||||
struct ramfs_inode *node = rlookup(priv, pathname);
|
||||
int len;
|
||||
|
||||
if (!node || !node->symlink)
|
||||
return -ENOENT;
|
||||
|
||||
len = min(bufsiz, strlen(node->symlink));
|
||||
|
||||
memcpy(buf, node->symlink, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ramfs_probe(struct device_d *dev)
|
||||
{
|
||||
struct ramfs_inode *n;
|
||||
|
@ -584,6 +631,8 @@ static struct fs_driver_d ramfs_driver = {
|
|||
.readdir = ramfs_readdir,
|
||||
.closedir = ramfs_closedir,
|
||||
.stat = ramfs_stat,
|
||||
.symlink = ramfs_symlink,
|
||||
.readlink = ramfs_readlink,
|
||||
.flags = FS_DRIVER_NO_DEV,
|
||||
.drv = {
|
||||
.probe = ramfs_probe,
|
||||
|
|
Loading…
Reference in New Issue