The open attr dir syscalls didn't work correctly in the FD modes.
fd_and_path_to_vnode() now accepts NULL as path argument. Added some more debug output and comments. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10368 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
4e0e3bf35d
commit
6780f6f417
@ -931,6 +931,10 @@ entry_ref_to_vnode(mount_id mountID, vnode_id directoryID, const char *name, str
|
||||
}
|
||||
|
||||
|
||||
/** Returns the vnode for the relative path starting at the specified \a vnode.
|
||||
* \a path must not be NULL.
|
||||
*/
|
||||
|
||||
static status_t
|
||||
vnode_path_to_vnode(struct vnode *vnode, char *path, bool traverseLeafLink,
|
||||
int count, struct vnode **_vnode, int *_type)
|
||||
@ -940,7 +944,7 @@ vnode_path_to_vnode(struct vnode *vnode, char *path, bool traverseLeafLink,
|
||||
|
||||
FUNCTION(("vnode_path_to_vnode(vnode = %p, path = %s)\n", vnode, path));
|
||||
|
||||
if (!path)
|
||||
if (path == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
while (true) {
|
||||
@ -1132,29 +1136,30 @@ path_to_dir_vnode(char *path, struct vnode **_vnode, char *filename, bool kernel
|
||||
|
||||
|
||||
/** \brief Retrieves the directory vnode and the leaf name of an entry referred
|
||||
to by a FD + path pair.
|
||||
* to by a FD + path pair.
|
||||
*
|
||||
* \a path must be given in either case. \a fd might be omitted, in which
|
||||
* case \a path is either an absolute path or one relative to the current
|
||||
* directory. If both a supplied and \a path is relative it is reckoned off
|
||||
* of the directory referred to by \a fd. If \a path is absolute \a fd is
|
||||
* ignored.
|
||||
*
|
||||
* The caller has the responsibility to call put_vnode() on the returned
|
||||
* directory vnode.
|
||||
*
|
||||
* \param fd The FD. May be < 0.
|
||||
* \param path The absolute or relative path. Must not be \c NULL. The buffer
|
||||
* is modified by this function. It must have at least room for a
|
||||
* string one character longer than the path it contains.
|
||||
* \param _vnode A pointer to a variable the directory vnode shall be written
|
||||
* into.
|
||||
* \param filename A buffer of size B_FILE_NAME_LENGTH or larger into which
|
||||
* the leaf name of the specified entry will be written.
|
||||
* \param kernel \c true, if invoked from inside the kernel, \c false if
|
||||
* invoked from userland.
|
||||
* \return \c B_OK, if everything went fine, another error code otherwise.
|
||||
*/
|
||||
|
||||
\a path must be given in either case. \a fd might be omitted, in which
|
||||
case \a path is either an absolute path or one relative to the current
|
||||
directory. If both a supplied and \a path is relative it is reckoned off
|
||||
of the directory referred to by \a fd. If \a path is absolute \a fd is
|
||||
ignored.
|
||||
|
||||
The caller has the responsibility to call put_vnode() on the returned
|
||||
directory vnode.
|
||||
|
||||
\param fd The FD. May be < 0.
|
||||
\param path The absolute or relative path. Must not be \c NULL. The buffer
|
||||
is modified by this function. It must have at least room for a
|
||||
string one character longer than the path it contains.
|
||||
\param _vnode A pointer to a variable the directory vnode shall be written
|
||||
into.
|
||||
\param filename A buffer of size B_FILE_NAME_LENGTH or larger into which
|
||||
the leaf name of the specified entry will be written.
|
||||
\param kernel \c true, if invoked from inside the kernel, \c false if
|
||||
invoked from userland.
|
||||
\return \c B_OK, if everything went fine, another error code otherwise.
|
||||
*/
|
||||
static status_t
|
||||
fd_and_path_to_dir_vnode(int fd, char *path, struct vnode **_vnode,
|
||||
char *filename, bool kernel)
|
||||
@ -1466,6 +1471,13 @@ get_vnode_from_fd(int fd, bool kernel)
|
||||
}
|
||||
|
||||
|
||||
/** Gets the vnode from an FD + path combination. If \a fd is lower than zero,
|
||||
* only the path will be considered. In this case, the \a path must not be
|
||||
* NULL.
|
||||
* If \a fd is a valid file descriptor, \a path may be NULL for directories,
|
||||
* and should be NULL for files.
|
||||
*/
|
||||
|
||||
static status_t
|
||||
fd_and_path_to_vnode(int fd, char *path, bool traverseLeafLink, struct vnode **_vnode, bool kernel)
|
||||
{
|
||||
@ -1474,7 +1486,7 @@ fd_and_path_to_vnode(int fd, char *path, bool traverseLeafLink, struct vnode **_
|
||||
|
||||
status_t status;
|
||||
struct vnode *vnode = NULL;
|
||||
if (fd < 0 || path[0] == '/') {
|
||||
if (fd < 0 || (path != NULL && path[0] == '/')) {
|
||||
// no FD or absolute path
|
||||
status = path_to_vnode(path, traverseLeafLink, &vnode, kernel);
|
||||
} else {
|
||||
@ -1482,8 +1494,12 @@ fd_and_path_to_vnode(int fd, char *path, bool traverseLeafLink, struct vnode **_
|
||||
vnode = get_vnode_from_fd(fd, kernel);
|
||||
if (!vnode)
|
||||
return B_FILE_ERROR;
|
||||
status = vnode_path_to_vnode(vnode, path, traverseLeafLink, 0, &vnode,
|
||||
NULL);
|
||||
|
||||
if (path != NULL) {
|
||||
status = vnode_path_to_vnode(vnode, path, traverseLeafLink, 0,
|
||||
&vnode, NULL);
|
||||
} else
|
||||
status = B_OK;
|
||||
}
|
||||
|
||||
if (status == B_OK)
|
||||
@ -3303,7 +3319,7 @@ common_path_write_stat(int fd, char *path, bool traverseLeafLink,
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
static int
|
||||
attr_dir_open(int fd, char *path, bool kernel)
|
||||
{
|
||||
struct vnode *vnode;
|
||||
@ -3328,7 +3344,7 @@ attr_dir_close(struct file_descriptor *descriptor)
|
||||
{
|
||||
struct vnode *vnode = descriptor->u.vnode;
|
||||
|
||||
FUNCTION(("dir_close(descriptor = %p)\n", descriptor));
|
||||
FUNCTION(("attr_dir_close(descriptor = %p)\n", descriptor));
|
||||
|
||||
if (FS_CALL(vnode, close_attr_dir))
|
||||
return FS_CALL(vnode, close_attr_dir)(vnode->mount->cookie, vnode->private_node, descriptor->cookie);
|
||||
@ -3354,6 +3370,8 @@ attr_dir_read(struct file_descriptor *descriptor, struct dirent *buffer, size_t
|
||||
{
|
||||
struct vnode *vnode = descriptor->u.vnode;
|
||||
|
||||
FUNCTION(("attr_dir_read(descriptor = %p)\n", descriptor));
|
||||
|
||||
if (FS_CALL(vnode, read_attr_dir))
|
||||
return FS_CALL(vnode, read_attr_dir)(vnode->mount->cookie, vnode->private_node, descriptor->cookie, buffer, bufferSize, _count);
|
||||
|
||||
@ -3366,6 +3384,8 @@ attr_dir_rewind(struct file_descriptor *descriptor)
|
||||
{
|
||||
struct vnode *vnode = descriptor->u.vnode;
|
||||
|
||||
FUNCTION(("attr_dir_rewind(descriptor = %p)\n", descriptor));
|
||||
|
||||
if (FS_CALL(vnode, rewind_attr_dir))
|
||||
return FS_CALL(vnode, rewind_attr_dir)(vnode->mount->cookie, vnode->private_node, descriptor->cookie);
|
||||
|
||||
@ -3434,6 +3454,7 @@ attr_open(int fd, const char *name, int openMode, bool kernel)
|
||||
if (status < B_OK)
|
||||
goto err;
|
||||
|
||||
// now we only need a file descriptor for this attribute and we're done
|
||||
if ((status = get_new_fd(FDTYPE_ATTR, vnode, cookie, openMode, kernel)) >= 0)
|
||||
return status;
|
||||
|
||||
@ -3549,6 +3570,7 @@ attr_read_stat(struct file_descriptor *descriptor, struct stat *stat)
|
||||
struct vnode *vnode = descriptor->u.vnode;
|
||||
|
||||
FUNCTION(("attr_read_stat: stat 0x%p\n", stat));
|
||||
|
||||
if (!FS_CALL(vnode, read_attr_stat))
|
||||
return EOPNOTSUPP;
|
||||
|
||||
@ -4919,10 +4941,10 @@ _kern_open_attr_dir(int fd, const char *path)
|
||||
{
|
||||
char pathBuffer[B_PATH_NAME_LENGTH + 1];
|
||||
|
||||
if (fd == -1)
|
||||
if (path != NULL)
|
||||
strlcpy(pathBuffer, path, B_PATH_NAME_LENGTH);
|
||||
|
||||
return attr_dir_open(fd, pathBuffer, true);
|
||||
return attr_dir_open(fd, path ? pathBuffer : NULL, true);
|
||||
}
|
||||
|
||||
|
||||
@ -5747,13 +5769,13 @@ _user_open_attr_dir(int fd, const char *userPath)
|
||||
{
|
||||
char pathBuffer[B_PATH_NAME_LENGTH + 1];
|
||||
|
||||
if (fd == -1) {
|
||||
if (userPath != NULL) {
|
||||
if (!IS_USER_ADDRESS(userPath)
|
||||
|| user_strlcpy(pathBuffer, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
return attr_dir_open(fd, pathBuffer, false);
|
||||
return attr_dir_open(fd, userPath ? pathBuffer : NULL, false);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user