Fixed bug #97:
* BEntry::Remove() now uses _kern_remove_dir() for directories. * Added fd parameter to _kern_remove_dir(). * Fixed LibBeAdapter's _kern_unlink() to only work on files, and added _kern_remove_dir() for directories. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16078 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -145,7 +145,7 @@ extern status_t _kern_fsync(int fd);
|
|||||||
extern off_t _kern_seek(int fd, off_t pos, int seekType);
|
extern off_t _kern_seek(int fd, off_t pos, int seekType);
|
||||||
extern status_t _kern_create_dir_entry_ref(dev_t device, ino_t inode, const char *name, int perms);
|
extern status_t _kern_create_dir_entry_ref(dev_t device, ino_t inode, const char *name, int perms);
|
||||||
extern status_t _kern_create_dir(int fd, const char *path, int perms);
|
extern status_t _kern_create_dir(int fd, const char *path, int perms);
|
||||||
extern status_t _kern_remove_dir(const char *path);
|
extern status_t _kern_remove_dir(int fd, const char *path);
|
||||||
extern status_t _kern_read_link(int fd, const char *path, char *buffer,
|
extern status_t _kern_read_link(int fd, const char *path, char *buffer,
|
||||||
size_t *_bufferSize);
|
size_t *_bufferSize);
|
||||||
extern status_t _kern_write_link(const char *path, const char *toPath);
|
extern status_t _kern_write_link(const char *path, const char *toPath);
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ status_t _user_write_stat(int fd, const char *path, bool traverseLink,
|
|||||||
off_t _user_seek(int fd, off_t pos, int seekType);
|
off_t _user_seek(int fd, off_t pos, int seekType);
|
||||||
status_t _user_create_dir_entry_ref(dev_t device, ino_t inode, const char *name, int perms);
|
status_t _user_create_dir_entry_ref(dev_t device, ino_t inode, const char *name, int perms);
|
||||||
status_t _user_create_dir(int fd, const char *path, int perms);
|
status_t _user_create_dir(int fd, const char *path, int perms);
|
||||||
status_t _user_remove_dir(const char *path);
|
status_t _user_remove_dir(int fd, const char *path);
|
||||||
status_t _user_read_link(int fd, const char *path, char *buffer, size_t *_bufferSize);
|
status_t _user_read_link(int fd, const char *path, char *buffer, size_t *_bufferSize);
|
||||||
status_t _user_write_link(const char *path, const char *toPath);
|
status_t _user_write_link(const char *path, const char *toPath);
|
||||||
status_t _user_create_symlink(int fd, const char *path, const char *toPath,
|
status_t _user_create_symlink(int fd, const char *path, const char *toPath,
|
||||||
|
|||||||
@@ -707,6 +707,10 @@ BEntry::Remove()
|
|||||||
{
|
{
|
||||||
if (fCStatus != B_OK)
|
if (fCStatus != B_OK)
|
||||||
return B_NO_INIT;
|
return B_NO_INIT;
|
||||||
|
|
||||||
|
if (IsDirectory())
|
||||||
|
return _kern_remove_dir(fDirFd, fName);
|
||||||
|
|
||||||
return _kern_unlink(fDirFd, fName);
|
return _kern_unlink(fDirFd, fName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -541,6 +541,24 @@ _kern_read_link(int fd, const char *path, char *buffer, size_t *_bufferSize)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// _kern_remove_dir
|
||||||
|
extern "C"
|
||||||
|
status_t
|
||||||
|
_kern_remove_dir(int fd, const char *relPath)
|
||||||
|
{
|
||||||
|
BPath path;
|
||||||
|
status_t error = get_path(fd, relPath, path);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (rmdir(path.Path()) < 0) {
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// _kern_unlink
|
// _kern_unlink
|
||||||
extern "C"
|
extern "C"
|
||||||
status_t
|
status_t
|
||||||
@@ -550,17 +568,14 @@ _kern_unlink(int fd, const char *relPath)
|
|||||||
status_t error = get_path(fd, relPath, path);
|
status_t error = get_path(fd, relPath, path);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
if (unlink(path.Path()) < 0) {
|
|
||||||
error = errno;
|
if (unlink(path.Path()) < 0)
|
||||||
if (error == B_IS_A_DIRECTORY) {
|
return errno;
|
||||||
if (rmdir(path.Path()) < 0)
|
|
||||||
return errno;
|
|
||||||
} else
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// _kern_rename
|
// _kern_rename
|
||||||
extern "C"
|
extern "C"
|
||||||
status_t
|
status_t
|
||||||
|
|||||||
@@ -3739,19 +3739,20 @@ dir_rewind(struct file_descriptor *descriptor)
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
dir_remove(char *path, bool kernel)
|
dir_remove(int fd, char *path, bool kernel)
|
||||||
{
|
{
|
||||||
char name[B_FILE_NAME_LENGTH];
|
char name[B_FILE_NAME_LENGTH];
|
||||||
struct vnode *directory;
|
struct vnode *directory;
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
status = path_to_dir_vnode(path, &directory, name, kernel);
|
status = fd_and_path_to_dir_vnode(fd, path, &directory, name, kernel);
|
||||||
if (status < B_OK)
|
if (status < 0)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if (FS_CALL(directory, remove_dir))
|
if (FS_CALL(directory, remove_dir)) {
|
||||||
status = FS_CALL(directory, remove_dir)(directory->mount->cookie, directory->private_node, name);
|
status = FS_CALL(directory, remove_dir)(directory->mount->cookie,
|
||||||
else
|
directory->private_node, name);
|
||||||
|
} else
|
||||||
status = EROFS;
|
status = EROFS;
|
||||||
|
|
||||||
put_vnode(directory);
|
put_vnode(directory);
|
||||||
@@ -5780,13 +5781,17 @@ _kern_create_dir(int fd, const char *path, int perms)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_kern_remove_dir(const char *path)
|
_kern_remove_dir(int fd, const char *path)
|
||||||
{
|
{
|
||||||
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
if (path) {
|
||||||
if (pathBuffer.InitCheck() != B_OK)
|
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
||||||
return B_NO_MEMORY;
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
return dir_remove(pathBuffer.LockBuffer(), true);
|
return dir_remove(fd, pathBuffer.LockBuffer(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dir_remove(fd, NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6634,19 +6639,15 @@ _user_create_dir(int fd, const char *userPath, int perms)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_user_remove_dir(const char *userPath)
|
_user_remove_dir(int fd, const char *userPath)
|
||||||
{
|
{
|
||||||
char path[B_PATH_NAME_LENGTH + 1];
|
char path[B_PATH_NAME_LENGTH + 1];
|
||||||
status_t status;
|
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userPath))
|
if ((userPath != NULL && !IS_USER_ADDRESS(userPath))
|
||||||
|
|| (userPath != NULL && user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK))
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
return dir_remove(fd, userPath ? path : NULL, false);
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
return dir_remove(path, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
* Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ getcwd(char *buffer, size_t size)
|
|||||||
int
|
int
|
||||||
rmdir(const char *path)
|
rmdir(const char *path)
|
||||||
{
|
{
|
||||||
int status = _kern_remove_dir(path);
|
int status = _kern_remove_dir(-1, path);
|
||||||
|
|
||||||
RETURN_AND_SET_ERRNO(status);
|
RETURN_AND_SET_ERRNO(status);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user