diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2015-12-10 09:31:02 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2016-01-08 08:30:55 +0100 |
commit | 8a35fddf572578eea4846aa440d3caba31f3cc37 (patch) | |
tree | f82987667b56c3ea4403161f4187a9d1f8deb7bb /fs/devfs.c | |
parent | 3cff8948ff5d2d4dc834bdc955684b73571713bd (diff) | |
download | barebox-8a35fddf572578eea4846aa440d3caba31f3cc37.tar.gz |
devfs: Add symlink support
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'fs/devfs.c')
-rw-r--r-- | fs/devfs.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/fs/devfs.c b/fs/devfs.c index 5c96682f96..0b8d4fd246 100644 --- a/fs/devfs.c +++ b/fs/devfs.c @@ -212,12 +212,18 @@ static int devfs_stat(struct device_d *_dev, const char *filename, struct stat * { struct cdev *cdev; - cdev = cdev_by_name(filename + 1); + cdev = lcdev_by_name(filename + 1); if (!cdev) return -ENOENT; s->st_mode = S_IFCHR; s->st_size = cdev->size; + + if (cdev->link) + s->st_mode |= S_IFLNK; + + cdev = cdev_readlink(cdev); + if (cdev->ops->write) s->st_mode |= S_IWUSR; if (cdev->ops->read) @@ -242,6 +248,24 @@ static void devfs_delete(struct device_d *dev) { } +static int devfs_readlink(struct device_d *dev, const char *pathname, + char *buf, size_t bufsz) +{ + struct cdev *cdev; + + cdev = cdev_by_name(pathname + 1); + if (!cdev) + return -ENOENT; + + while (cdev->link) + cdev = cdev->link; + + bufsz = min(bufsz, strlen(cdev->name)); + memcpy(buf, cdev->name, bufsz); + + return 0; +} + static struct fs_driver_d devfs_driver = { .read = devfs_read, .write = devfs_write, @@ -258,6 +282,7 @@ static struct fs_driver_d devfs_driver = { .erase = devfs_erase, .protect = devfs_protect, .memmap = devfs_memmap, + .readlink = devfs_readlink, .flags = FS_DRIVER_NO_DEV, .drv = { .probe = devfs_probe, |