* Factored a vfs_entry_ref_to_path() out of _user_entry_ref_to_path()
and made it public (within the kernel). * _user_entry_ref_to_path() is now using that function. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24151 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
4454eadeb4
commit
4f26630d82
@ -107,6 +107,8 @@ status_t vfs_get_fs_node_from_path(dev_t mountID, const char *path,
|
||||
bool kernel, void **_node);
|
||||
status_t vfs_stat_vnode(struct vnode *vnode, struct stat *stat);
|
||||
status_t vfs_get_vnode_name(struct vnode *vnode, char *name, size_t nameSize);
|
||||
status_t vfs_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
|
||||
char *path, size_t pathLength);
|
||||
status_t vfs_get_cwd(dev_t *_mountID, ino_t *_vnodeID);
|
||||
void vfs_unlock_vnode_if_locked(struct file_descriptor *descriptor);
|
||||
status_t vfs_unmount(dev_t mountID, uint32 flags);
|
||||
|
@ -3639,6 +3639,49 @@ vfs_get_vnode_name(struct vnode *vnode, char *name, size_t nameSize)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vfs_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
|
||||
char *path, size_t pathLength)
|
||||
{
|
||||
struct vnode *vnode;
|
||||
status_t status;
|
||||
|
||||
// filter invalid leaf names
|
||||
if (leaf[0] == '\0' || strchr(leaf, '/'))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get the vnode matching the dir's node_ref
|
||||
if (leaf && (strcmp(leaf, ".") == 0 || strcmp(leaf, "..") == 0)) {
|
||||
// special cases "." and "..": we can directly get the vnode of the
|
||||
// referenced directory
|
||||
status = entry_ref_to_vnode(device, inode, leaf, &vnode);
|
||||
leaf = NULL;
|
||||
} else
|
||||
status = get_vnode(device, inode, &vnode, true, false);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
// get the directory path
|
||||
status = dir_vnode_to_path(vnode, path, pathLength);
|
||||
put_vnode(vnode);
|
||||
// we don't need the vnode anymore
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
// append the leaf name
|
||||
if (leaf) {
|
||||
// insert a directory separator if this is not the file system root
|
||||
if ((strcmp(path, "/") && strlcat(path, "/", pathLength)
|
||||
>= pathLength)
|
||||
|| strlcat(path, leaf, pathLength) >= pathLength) {
|
||||
return B_NAME_TOO_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/*! If the given descriptor locked its vnode, that lock will be released. */
|
||||
void
|
||||
vfs_unlock_vnode_if_locked(struct file_descriptor *descriptor)
|
||||
@ -7216,68 +7259,39 @@ status_t
|
||||
_user_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
|
||||
char *userPath, size_t pathLength)
|
||||
{
|
||||
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||
if (pathBuffer.InitCheck() != B_OK)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
struct vnode *vnode;
|
||||
status_t status;
|
||||
|
||||
if (!IS_USER_ADDRESS(userPath))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
KPath path(B_PATH_NAME_LENGTH + 1);
|
||||
if (path.InitCheck() != B_OK)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
// copy the leaf name onto the stack
|
||||
char stackLeaf[B_FILE_NAME_LENGTH];
|
||||
if (leaf) {
|
||||
if (!IS_USER_ADDRESS(leaf))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
int len = user_strlcpy(stackLeaf, leaf, B_FILE_NAME_LENGTH);
|
||||
if (len < 0)
|
||||
return len;
|
||||
if (len >= B_FILE_NAME_LENGTH)
|
||||
int length = user_strlcpy(stackLeaf, leaf, B_FILE_NAME_LENGTH);
|
||||
if (length < 0)
|
||||
return length;
|
||||
if (length >= B_FILE_NAME_LENGTH)
|
||||
return B_NAME_TOO_LONG;
|
||||
|
||||
leaf = stackLeaf;
|
||||
|
||||
// filter invalid leaf names
|
||||
if (leaf[0] == '\0' || strchr(leaf, '/'))
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// get the vnode matching the dir's node_ref
|
||||
if (leaf && (strcmp(leaf, ".") == 0 || strcmp(leaf, "..") == 0)) {
|
||||
// special cases "." and "..": we can directly get the vnode of the
|
||||
// referenced directory
|
||||
status = entry_ref_to_vnode(device, inode, leaf, &vnode);
|
||||
leaf = NULL;
|
||||
} else
|
||||
status = get_vnode(device, inode, &vnode, true, false);
|
||||
status_t status = vfs_entry_ref_to_path(device, inode, leaf,
|
||||
path.LockBuffer(), path.BufferSize());
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
char *path = pathBuffer.LockBuffer();
|
||||
path.UnlockBuffer();
|
||||
|
||||
// get the directory path
|
||||
status = dir_vnode_to_path(vnode, path, pathBuffer.BufferSize());
|
||||
put_vnode(vnode);
|
||||
// we don't need the vnode anymore
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
// append the leaf name
|
||||
if (leaf) {
|
||||
// insert a directory separator if this is not the file system root
|
||||
if ((strcmp(path, "/") && strlcat(path, "/", pathBuffer.BufferSize())
|
||||
>= pathBuffer.BufferSize())
|
||||
|| strlcat(path, leaf, pathBuffer.BufferSize()) >= pathBuffer.BufferSize()) {
|
||||
return B_NAME_TOO_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
int len = user_strlcpy(userPath, path, pathLength);
|
||||
if (len < 0)
|
||||
return len;
|
||||
if (len >= (int)pathLength)
|
||||
int length = user_strlcpy(userPath, path.Path(), pathLength);
|
||||
if (length < 0)
|
||||
return length;
|
||||
if (length >= (int)pathLength)
|
||||
return B_BUFFER_OVERFLOW;
|
||||
|
||||
return B_OK;
|
||||
|
Loading…
x
Reference in New Issue
Block a user