diff options
-rw-r--r-- | sys/include/sys/vfs.h | 1 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 57 |
2 files changed, 58 insertions, 0 deletions
diff --git a/sys/include/sys/vfs.h b/sys/include/sys/vfs.h index 7aafecf..6b96cce 100644 --- a/sys/include/sys/vfs.h +++ b/sys/include/sys/vfs.h @@ -40,6 +40,7 @@ struct fs_info *vfs_byname(const char *name); struct vnode *vfs_path_to_node(const char *path); char *vfs_get_fname_at(const char *path, size_t idx); +int vfs_rootname(const char *path, char **new_path); bool vfs_is_valid_path(const char *path); ssize_t vfs_hash_path(const char *path); #endif /* defined(_KERNEL) */ diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 5338a8c..5740edf 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -159,3 +159,60 @@ vfs_alloc_vnode(struct vnode **vnode, struct mount *mp, int type) *vnode = new_vnode; return 0; } + +/* + * Returns the rootname of a path + * For example, "/foo/bar/" will be "foo" and + * "/foo/bar/baz" will also be "foo" + * + * There will be no slashes in the returned string + * unless "/" is passed. + * + * XXX: Returns memory allocated by dynalloc, + * remember to free the memory with dynfree() + * + * @path: Path to get rootname of + * @new_path: New path will be placed here. + */ +int +vfs_rootname(const char *path, char **new_path) +{ + char *tmp = NULL; + const char *ptr = path; + size_t len = 0; + + if (!vfs_is_valid_path(path)) { + *new_path = NULL; + return -EINVAL; + } + + if (*path == '/') { + /* Skip first '/' */ + ++ptr; + ++path; + } + + for (; *ptr != '\0' && *ptr != '/'; ++ptr) { + if (*ptr == '/') { + break; + } + ++len; + } + + tmp = dynalloc(sizeof(char) * len + 1); + if (tmp == NULL) { + *new_path = NULL; + return -ENOMEM; + } + + if (len == 0) { + /* Handle input that is just "/" */ + tmp[0] = '/'; + tmp[1] = '\0'; + } else { + memcpy(tmp, path, len + 2); + } + + *new_path = tmp; + return 0; +} |