The fs interface functions should now return a "status_t" rather than an "int".
Added syscalls for, and implemented sys_create_link(), sys_remove_dir(). Implemented link(), unlink(), rmdir(). Fixed the inconsistent path buffer handling in the user|sys vfs functions; the path buffer is now exactly SYS_MAX_PATH_LEN from userland (incl. terminating null byte). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@748 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
11e946307a
commit
4c405cbdd4
@ -42,87 +42,89 @@ extern "C" {
|
||||
|
||||
struct fs_calls {
|
||||
/* general operations */
|
||||
int (*fs_mount)(fs_id id, const char *device, void *args, fs_cookie *_fs, vnode_id *_rootVnodeID);
|
||||
int (*fs_unmount)(fs_cookie fs);
|
||||
status_t (*fs_mount)(fs_id id, const char *device, void *args, fs_cookie *_fs, vnode_id *_rootVnodeID);
|
||||
status_t (*fs_unmount)(fs_cookie fs);
|
||||
|
||||
int (*fs_read_fs_info)(fs_cookie fs, struct fs_info *info);
|
||||
int (*fs_write_fs_info)(fs_cookie fs, const struct fs_info *info, int mask);
|
||||
int (*fs_sync)(fs_cookie fs);
|
||||
status_t (*fs_read_fs_info)(fs_cookie fs, struct fs_info *info);
|
||||
status_t (*fs_write_fs_info)(fs_cookie fs, const struct fs_info *info, int mask);
|
||||
status_t (*fs_sync)(fs_cookie fs);
|
||||
|
||||
/* vnode operations */
|
||||
int (*fs_lookup)(fs_cookie fs, fs_vnode dir, const char *name, vnode_id *_id, int *_type);
|
||||
int (*fs_get_vnode_name)(fs_cookie fs, fs_vnode vnode, char *buffer, size_t bufferSize);
|
||||
status_t (*fs_lookup)(fs_cookie fs, fs_vnode dir, const char *name, vnode_id *_id, int *_type);
|
||||
status_t (*fs_get_vnode_name)(fs_cookie fs, fs_vnode vnode, char *buffer, size_t bufferSize);
|
||||
|
||||
int (*fs_get_vnode)(fs_cookie fs, vnode_id id, fs_vnode *_vnode, bool reenter);
|
||||
int (*fs_put_vnode)(fs_cookie fs, fs_vnode vnode, bool reenter);
|
||||
int (*fs_remove_vnode)(fs_cookie fs, fs_vnode vnode, bool reenter);
|
||||
status_t (*fs_get_vnode)(fs_cookie fs, vnode_id id, fs_vnode *_vnode, bool reenter);
|
||||
status_t (*fs_put_vnode)(fs_cookie fs, fs_vnode vnode, bool reenter);
|
||||
status_t (*fs_remove_vnode)(fs_cookie fs, fs_vnode vnode, bool reenter);
|
||||
|
||||
/* VM file access */
|
||||
int (*fs_can_page)(fs_cookie fs, fs_vnode v);
|
||||
status_t (*fs_can_page)(fs_cookie fs, fs_vnode v);
|
||||
ssize_t (*fs_read_page)(fs_cookie fs, fs_vnode v, iovecs *vecs, off_t pos);
|
||||
ssize_t (*fs_write_page)(fs_cookie fs, fs_vnode v, iovecs *vecs, off_t pos);
|
||||
|
||||
/* common operations */
|
||||
int (*fs_ioctl)(fs_cookie fs, fs_vnode v, file_cookie cookie, ulong op, void *buffer, size_t length);
|
||||
int (*fs_fsync)(fs_cookie fs, fs_vnode v);
|
||||
status_t (*fs_ioctl)(fs_cookie fs, fs_vnode v, file_cookie cookie, ulong op, void *buffer, size_t length);
|
||||
status_t (*fs_fsync)(fs_cookie fs, fs_vnode v);
|
||||
|
||||
int (*fs_read_link)(fs_cookie fs, fs_vnode link, char *buffer, size_t bufferSize);
|
||||
int (*fs_write_link)(fs_cookie fs, fs_vnode link, char *toPath);
|
||||
int (*fs_symlink)(fs_cookie fs, fs_vnode dir, const char *name, const char *path, int mode);
|
||||
status_t (*fs_read_link)(fs_cookie fs, fs_vnode link, char *buffer, size_t bufferSize);
|
||||
status_t (*fs_write_link)(fs_cookie fs, fs_vnode link, char *toPath);
|
||||
status_t (*fs_create_symlink)(fs_cookie fs, fs_vnode dir, const char *name, const char *path, int mode);
|
||||
|
||||
int (*fs_unlink)(fs_cookie fs, fs_vnode dir, const char *name);
|
||||
int (*fs_rename)(fs_cookie fs, fs_vnode olddir, const char *oldname, fs_vnode newdir, const char *newname);
|
||||
status_t (*fs_link)(fs_cookie fs, fs_vnode dir, const char *name, fs_vnode vnode);
|
||||
status_t (*fs_unlink)(fs_cookie fs, fs_vnode dir, const char *name);
|
||||
status_t (*fs_rename)(fs_cookie fs, fs_vnode olddir, const char *oldname, fs_vnode newdir, const char *newname);
|
||||
|
||||
int (*fs_access)(fs_cookie fs, fs_vnode vnode, int mode);
|
||||
int (*fs_read_stat)(fs_cookie fs, fs_vnode vnode, struct stat *stat);
|
||||
int (*fs_write_stat)(fs_cookie fs, fs_vnode vnode, const struct stat *stat, int statMask);
|
||||
status_t (*fs_access)(fs_cookie fs, fs_vnode vnode, int mode);
|
||||
status_t (*fs_read_stat)(fs_cookie fs, fs_vnode vnode, struct stat *stat);
|
||||
status_t (*fs_write_stat)(fs_cookie fs, fs_vnode vnode, const struct stat *stat, int statMask);
|
||||
|
||||
/* file operations */
|
||||
int (*fs_create)(fs_cookie fs, fs_vnode dir, const char *name, int omode, int perms, file_cookie *_cookie, vnode_id *_newVnodeID);
|
||||
int (*fs_open)(fs_cookie fs, fs_vnode v, int oflags, file_cookie *_cookie);
|
||||
int (*fs_close)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
int (*fs_free_cookie)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
status_t (*fs_create)(fs_cookie fs, fs_vnode dir, const char *name, int omode, int perms, file_cookie *_cookie, vnode_id *_newVnodeID);
|
||||
status_t (*fs_open)(fs_cookie fs, fs_vnode v, int oflags, file_cookie *_cookie);
|
||||
status_t (*fs_close)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
status_t (*fs_free_cookie)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
ssize_t (*fs_read)(fs_cookie fs, fs_vnode v, file_cookie cookie, off_t pos, void *buffer, size_t *length);
|
||||
ssize_t (*fs_write)(fs_cookie fs, fs_vnode v, file_cookie cookie, off_t pos, const void *buffer, size_t *length);
|
||||
off_t (*fs_seek)(fs_cookie fs, fs_vnode v, file_cookie cookie, off_t pos, int seekType);
|
||||
|
||||
/* directory operations */
|
||||
int (*fs_create_dir)(fs_cookie fs, fs_vnode parent, const char *name, int perms, vnode_id *_newVnodeID);
|
||||
int (*fs_open_dir)(fs_cookie fs, fs_vnode v, file_cookie *_cookie);
|
||||
int (*fs_close_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
int (*fs_free_dir_cookie)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
int (*fs_read_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie, struct dirent *buffer, size_t bufferSize, uint32 *_num);
|
||||
int (*fs_rewind_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
status_t (*fs_create_dir)(fs_cookie fs, fs_vnode parent, const char *name, int perms, vnode_id *_newVnodeID);
|
||||
status_t (*fs_remove_dir)(fs_cookie fs, fs_vnode dir, const char *name);
|
||||
status_t (*fs_open_dir)(fs_cookie fs, fs_vnode v, file_cookie *_cookie);
|
||||
status_t (*fs_close_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
status_t (*fs_free_dir_cookie)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
status_t (*fs_read_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie, struct dirent *buffer, size_t bufferSize, uint32 *_num);
|
||||
status_t (*fs_rewind_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
|
||||
/* attribute directory operations */
|
||||
// int (*fs_open_attr_dir)(fs_cookie fs, fs_vnode v, file_cookie *cookie, int oflags);
|
||||
// int (*fs_close_attr_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// int (*fs_free_attr_dir_cookie)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// int (*fs_read_attr_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie, struct dirent *buffer, size_t bufferSize, uint32 *_num);
|
||||
// int (*fs_rewind_attr_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// status_t (*fs_open_attr_dir)(fs_cookie fs, fs_vnode v, file_cookie *cookie, int oflags);
|
||||
// status_t (*fs_close_attr_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// status_t (*fs_free_attr_dir_cookie)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// status_t (*fs_read_attr_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie, struct dirent *buffer, size_t bufferSize, uint32 *_num);
|
||||
// status_t (*fs_rewind_attr_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
//
|
||||
// /* attribute operations */
|
||||
// int (*fs_open_attr)(fs_cookie fs, fs_vnode v, file_cookie *cookie, stream_type st, int oflags);
|
||||
// int (*fs_close_attr)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// int (*fs_free_attr_cookie)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// status_t (*fs_open_attr)(fs_cookie fs, fs_vnode v, file_cookie *cookie, stream_type st, int oflags);
|
||||
// status_t (*fs_close_attr)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// status_t (*fs_free_attr_cookie)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// ssize_t (*fs_read_attr)(fs_cookie fs, fs_vnode v, file_cookie cookie, void *buf, off_t pos, size_t *len);
|
||||
// ssize_t (*fs_write_attr)(fs_cookie fs, fs_vnode v, file_cookie cookie, const void *buf, off_t pos, size_t *len);
|
||||
// int (*fs_seek_attr)(fs_cookie fs, fs_vnode v, file_cookie cookie, off_t pos, int st);
|
||||
// int (*fs_rename_attr)(fs_cookie fs, fs_vnode file, const char *oldname, const char *newname);
|
||||
// status_t (*fs_seek_attr)(fs_cookie fs, fs_vnode v, file_cookie cookie, off_t pos, int st);
|
||||
// status_t (*fs_rename_attr)(fs_cookie fs, fs_vnode file, const char *oldname, const char *newname);
|
||||
//
|
||||
// /* index directory & index operations */
|
||||
// int (*fs_open_index_dir)(fs_cookie fs, fs_vnode v, file_cookie *cookie, int oflags);
|
||||
// int (*fs_close_index_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// int (*fs_free_index_dir_cookie)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// int (*fs_read_index_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie, struct dirent *buffer, size_t bufferSize, uint32 *_num);
|
||||
// int (*fs_rewind_index_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// status_t (*fs_open_index_dir)(fs_cookie fs, fs_vnode v, file_cookie *cookie, int oflags);
|
||||
// status_t (*fs_close_index_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// status_t (*fs_free_index_dir_cookie)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// status_t (*fs_read_index_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie, struct dirent *buffer, size_t bufferSize, uint32 *_num);
|
||||
// status_t (*fs_rewind_index_dir)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
//
|
||||
// /* query operations */
|
||||
// int (*fs_open_query)(fs_cookie fs, fs_vnode v, file_cookie *cookie, int oflags);
|
||||
// int (*fs_close_query)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// int (*fs_free_query_cookie)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// int (*fs_read_query)(fs_cookie fs, fs_vnode v, file_cookie cookie, struct dirent *buffer, size_t bufferSize, uint32 *_num);
|
||||
// int (*fs_rewind_query)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// status_t (*fs_open_query)(fs_cookie fs, fs_vnode v, file_cookie *cookie, int oflags);
|
||||
// status_t (*fs_close_query)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// status_t (*fs_free_query_cookie)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
// status_t (*fs_read_query)(fs_cookie fs, fs_vnode v, file_cookie cookie, struct dirent *buffer, size_t bufferSize, uint32 *_num);
|
||||
// status_t (*fs_rewind_query)(fs_cookie fs, fs_vnode v, file_cookie cookie);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -77,9 +77,9 @@ extern char *getcwd(char *buffer, size_t size);
|
||||
extern int dup(int fd);
|
||||
extern int dup2(int fd1, int fd2);
|
||||
extern int close(int fd);
|
||||
//extern int link(const char *name, const char *new_name);
|
||||
//extern int unlink(const char *name);
|
||||
//extern int rmdir(const char *path);
|
||||
extern int link(const char *name, const char *new_name);
|
||||
extern int unlink(const char *name);
|
||||
extern int rmdir(const char *path);
|
||||
|
||||
extern ssize_t readlink(const char *path, char *buffer, size_t bufferSize);
|
||||
extern int symlink(const char *from, const char *to);
|
||||
|
@ -100,6 +100,8 @@ enum {
|
||||
SYSCALL_GET_NEXT_THREAD_INFO,
|
||||
SYSCALL_GET_TEAM_INFO, /* 90 */
|
||||
SYSCALL_GET_NEXT_TEAM_INFO,
|
||||
SYSCALL_CREATE_LINK,
|
||||
SYSCALL_REMOVE_DIR,
|
||||
};
|
||||
|
||||
int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_ret);
|
||||
|
@ -72,9 +72,11 @@ int sys_create_entry_ref(dev_t device, ino_t inode, const char *uname, int omode
|
||||
int sys_create(const char *path, int omode, int perms);
|
||||
int sys_create_dir_entry_ref(dev_t device, ino_t inode, const char *name, int perms);
|
||||
int sys_create_dir(const char *path, int perms);
|
||||
int sys_remove_dir(const char *path);
|
||||
int sys_read_link(const char *path, char *buffer, size_t bufferSize);
|
||||
int sys_write_link(const char *path, const char *toPath);
|
||||
int sys_create_symlink(const char *path, const char *toPath, int mode);
|
||||
int sys_create_link(const char *path, const char *toPath);
|
||||
int sys_unlink(const char *path);
|
||||
int sys_rename(const char *oldpath, const char *newpath);
|
||||
int sys_access(const char *path, int mode);
|
||||
@ -98,9 +100,11 @@ int user_create_entry_ref(dev_t device, ino_t inode, const char *uname, int omod
|
||||
int user_create(const char *path, int omode, int perms);
|
||||
int user_create_dir_entry_ref(dev_t device, ino_t inode, const char *name, int perms);
|
||||
int user_create_dir(const char *path, int perms);
|
||||
int user_remove_dir(const char *path);
|
||||
int user_read_link(const char *path, char *buffer, size_t bufferSize);
|
||||
int user_write_link(const char *path, const char *toPath);
|
||||
int user_create_symlink(const char *path, const char *toPath, int mode);
|
||||
int user_create_link(const char *path, const char *toPath);
|
||||
int user_unlink(const char *path);
|
||||
int user_rename(const char *oldpath, const char *newpath);
|
||||
int user_access(const char *path, int mode);
|
||||
|
@ -1031,6 +1031,7 @@ static struct fs_calls bootfs_calls = {
|
||||
NULL, // read_link
|
||||
NULL, // write_link
|
||||
NULL, // symlink
|
||||
NULL, // link
|
||||
&bootfs_unlink,
|
||||
&bootfs_rename,
|
||||
|
||||
@ -1049,6 +1050,7 @@ static struct fs_calls bootfs_calls = {
|
||||
|
||||
/* dir */
|
||||
&bootfs_create_dir,
|
||||
NULL, // remove_dir
|
||||
&bootfs_open_dir,
|
||||
&bootfs_close, // we are using the same operations for directories
|
||||
&bootfs_free_cookie, // and files here - that's intended, not by accident
|
||||
|
@ -998,7 +998,7 @@ devfs_unlink(fs_cookie _fs, fs_vnode _dir, const char *name)
|
||||
|
||||
status = vfs_remove_vnode(fs->id, vnode->id);
|
||||
|
||||
err:
|
||||
err:
|
||||
mutex_unlock(&fs->lock);
|
||||
|
||||
return status;
|
||||
@ -1069,6 +1069,7 @@ static struct fs_calls devfs_calls = {
|
||||
NULL, // read_link
|
||||
NULL, // write_link
|
||||
NULL, // symlink
|
||||
NULL, // link
|
||||
&devfs_unlink,
|
||||
&devfs_rename,
|
||||
|
||||
@ -1087,6 +1088,7 @@ static struct fs_calls devfs_calls = {
|
||||
|
||||
/* directory */
|
||||
&devfs_create_dir,
|
||||
NULL, // remove_dir
|
||||
&devfs_open_dir,
|
||||
&devfs_close, // we are using the same operations for directories
|
||||
&devfs_free_cookie, // and files here - that's intended, not by accident
|
||||
|
@ -225,6 +225,39 @@ rootfs_is_dir_empty(struct rootfs_vnode *dir)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
rootfs_remove(struct rootfs *fs, struct rootfs_vnode *dir, const char *name, bool isDirectory)
|
||||
{
|
||||
struct rootfs_vnode *vnode;
|
||||
int status = B_OK;
|
||||
|
||||
mutex_lock(&fs->lock);
|
||||
|
||||
vnode = rootfs_find_in_dir(dir, name);
|
||||
if (!vnode)
|
||||
status = B_ENTRY_NOT_FOUND;
|
||||
else if (isDirectory && vnode->stream.type != STREAM_TYPE_DIR)
|
||||
status = B_NOT_A_DIRECTORY;
|
||||
else if (!isDirectory && vnode->stream.type == STREAM_TYPE_DIR)
|
||||
status = B_IS_A_DIRECTORY;
|
||||
else if (isDirectory && !rootfs_is_dir_empty(vnode))
|
||||
status = B_DIRECTORY_NOT_EMPTY;
|
||||
|
||||
if (status < B_OK)
|
||||
goto err;
|
||||
|
||||
rootfs_remove_from_dir(dir, vnode);
|
||||
|
||||
// schedule this vnode to be removed when it's ref goes to zero
|
||||
vfs_remove_vnode(fs->id, vnode->id);
|
||||
|
||||
err:
|
||||
mutex_unlock(&fs->lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
@ -565,6 +598,18 @@ err:
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
rootfs_remove_dir(fs_cookie _fs, fs_vnode _dir, const char *name)
|
||||
{
|
||||
struct rootfs *fs = _fs;
|
||||
struct rootfs_vnode *dir = _dir;
|
||||
|
||||
TRACE(("rootfs_remove_dir: dir 0x%x (0x%x 0x%x), name '%s'\n", dir, dir->id, name));
|
||||
|
||||
return rootfs_remove(fs, dir, name, true);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
rootfs_open_dir(fs_cookie _fs, fs_vnode _v, file_cookie *_cookie)
|
||||
{
|
||||
@ -759,36 +804,10 @@ rootfs_unlink(fs_cookie _fs, fs_vnode _dir, const char *name)
|
||||
{
|
||||
struct rootfs *fs = _fs;
|
||||
struct rootfs_vnode *dir = _dir;
|
||||
struct rootfs_vnode *vnode;
|
||||
int status;
|
||||
|
||||
TRACE(("rootfs_unlink: dir 0x%x (0x%x 0x%x), name '%s'\n", dir, dir->id, name));
|
||||
|
||||
mutex_lock(&fs->lock);
|
||||
|
||||
vnode = rootfs_find_in_dir(dir, name);
|
||||
if (!vnode) {
|
||||
status = B_ENTRY_NOT_FOUND;
|
||||
goto err;
|
||||
}
|
||||
|
||||
// if the node is a directory, only delete it if it's empty
|
||||
if (vnode->stream.type == STREAM_TYPE_DIR && !rootfs_is_dir_empty(vnode)) {
|
||||
status = B_DIRECTORY_NOT_EMPTY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
rootfs_remove_from_dir(dir, vnode);
|
||||
|
||||
// schedule this vnode to be removed when it's ref goes to zero
|
||||
vfs_remove_vnode(fs->id, vnode->id);
|
||||
|
||||
status = 0;
|
||||
|
||||
err:
|
||||
mutex_unlock(&fs->lock);
|
||||
|
||||
return status;
|
||||
return rootfs_remove(fs, dir, name, false);
|
||||
}
|
||||
|
||||
|
||||
@ -922,6 +941,7 @@ static struct fs_calls rootfs_calls = {
|
||||
&rootfs_read_link,
|
||||
NULL, // fs_write_link()
|
||||
&rootfs_symlink,
|
||||
NULL, // fs_link()
|
||||
&rootfs_unlink,
|
||||
&rootfs_rename,
|
||||
|
||||
@ -940,6 +960,7 @@ static struct fs_calls rootfs_calls = {
|
||||
|
||||
/* directory */
|
||||
&rootfs_create_dir,
|
||||
&rootfs_remove_dir,
|
||||
&rootfs_open_dir,
|
||||
&rootfs_close, // we are using the same operations for directories
|
||||
&rootfs_free_cookie, // and files here - that's intended, not by accident
|
||||
|
@ -730,6 +730,7 @@ path_to_vnode(char *path, bool traverseLink, struct vnode **_vnode, bool kernel)
|
||||
|
||||
/** Returns the vnode in the next to last segment of the path, and returns
|
||||
* the last portion in filename.
|
||||
* The path buffer must be able to store at least one additional character.
|
||||
*/
|
||||
|
||||
static int
|
||||
@ -746,7 +747,6 @@ path_to_dir_vnode(char *path, struct vnode **_vnode, char *filename, bool kernel
|
||||
// replace the filename portion of the path with a '.'
|
||||
strcpy(filename, ++p);
|
||||
|
||||
// ToDo: this could write behind the array limit
|
||||
if (p[0] != '\0'){
|
||||
p[0] = '.';
|
||||
p[1] = '\0';
|
||||
@ -899,6 +899,12 @@ out:
|
||||
}
|
||||
|
||||
|
||||
/** Checks the length of every path component, and adds a '.'
|
||||
* if the path ends in a slash.
|
||||
* The given path buffer must be able to store at least one
|
||||
* additional character.
|
||||
*/
|
||||
|
||||
static status_t
|
||||
check_path(char *to)
|
||||
{
|
||||
@ -1975,6 +1981,27 @@ dir_close(struct file_descriptor *descriptor)
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
dir_remove(char *path, bool kernel)
|
||||
{
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
struct vnode *directory;
|
||||
status_t status;
|
||||
|
||||
status = path_to_dir_vnode(path, &directory, name, kernel);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
if (FS_CALL(directory, fs_remove_dir))
|
||||
status = FS_CALL(directory, fs_remove_dir)(directory->mount->cookie, directory->private_node, name);
|
||||
else
|
||||
status = EROFS;
|
||||
|
||||
put_vnode(directory);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
common_read_stat(struct file_descriptor *descriptor, struct stat *stat)
|
||||
{
|
||||
@ -2062,7 +2089,7 @@ common_write_link(char *path, char *toPath, bool kernel)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
static status_t
|
||||
common_create_symlink(char *path, const char *toPath, int mode, bool kernel)
|
||||
{
|
||||
// path validity checks have to be in the calling function!
|
||||
@ -2070,14 +2097,14 @@ common_create_symlink(char *path, const char *toPath, int mode, bool kernel)
|
||||
struct vnode *vnode;
|
||||
int status;
|
||||
|
||||
FUNCTION(("common_create_alias(path = %s, toPath = %s, mode = %d, kernel = %d)\n", path, toPath, mode, kernel));
|
||||
FUNCTION(("common_create_symlink(path = %s, toPath = %s, mode = %d, kernel = %d)\n", path, toPath, mode, kernel));
|
||||
|
||||
status = path_to_dir_vnode(path, &vnode, name, kernel);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
if (FS_CALL(vnode,fs_symlink) != NULL)
|
||||
status = FS_CALL(vnode,fs_symlink)(vnode->mount->cookie, vnode->private_node, name, toPath, mode);
|
||||
if (FS_CALL(vnode,fs_create_symlink) != NULL)
|
||||
status = FS_CALL(vnode,fs_create_symlink)(vnode->mount->cookie, vnode->private_node, name, toPath, mode);
|
||||
else
|
||||
status = EROFS;
|
||||
|
||||
@ -2087,7 +2114,44 @@ common_create_symlink(char *path, const char *toPath, int mode, bool kernel)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
static status_t
|
||||
common_create_link(char *path, char *toPath, bool kernel)
|
||||
{
|
||||
// path validity checks have to be in the calling function!
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
struct vnode *directory, *vnode;
|
||||
int status;
|
||||
|
||||
FUNCTION(("common_create_link(path = %s, toPath = %s, kernel = %d)\n", path, toPath, kernel));
|
||||
|
||||
status = path_to_dir_vnode(path, &directory, name, kernel);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
status = path_to_vnode(toPath, true, &vnode, kernel);
|
||||
if (status < B_OK)
|
||||
goto err;
|
||||
|
||||
if (directory->mount != vnode->mount) {
|
||||
status = B_CROSS_DEVICE_LINK;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
if (FS_CALL(vnode, fs_link) != NULL)
|
||||
status = FS_CALL(vnode,fs_link)(directory->mount->cookie, directory->private_node, name, vnode->private_node);
|
||||
else
|
||||
status = EROFS;
|
||||
|
||||
err1:
|
||||
put_vnode(vnode);
|
||||
err:
|
||||
put_vnode(directory);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
common_unlink(char *path, bool kernel)
|
||||
{
|
||||
char filename[SYS_MAX_NAME_LEN];
|
||||
@ -2548,24 +2612,20 @@ err:
|
||||
int
|
||||
sys_mount(const char *path, const char *device, const char *fs_name, void *args)
|
||||
{
|
||||
char buf[SYS_MAX_PATH_LEN + 1];
|
||||
char pathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
strlcpy(pathBuffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
strncpy(buf, path, SYS_MAX_PATH_LEN);
|
||||
buf[SYS_MAX_PATH_LEN] = 0;
|
||||
|
||||
return fs_mount(buf, device, fs_name, args, true);
|
||||
return fs_mount(pathBuffer, device, fs_name, args, true);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sys_unmount(const char *path)
|
||||
{
|
||||
char buf[SYS_MAX_PATH_LEN + 1];
|
||||
char pathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
strlcpy(pathBuffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
strncpy(buf, path, SYS_MAX_PATH_LEN);
|
||||
buf[SYS_MAX_PATH_LEN] = 0;
|
||||
|
||||
return fs_unmount(buf, true);
|
||||
return fs_unmount(pathBuffer, true);
|
||||
}
|
||||
|
||||
|
||||
@ -2580,9 +2640,7 @@ int
|
||||
sys_open_entry_ref(dev_t device, ino_t inode, const char *name, int omode)
|
||||
{
|
||||
char nameCopy[B_FILE_NAME_LENGTH];
|
||||
|
||||
strncpy(nameCopy, name, sizeof(nameCopy) - 1);
|
||||
nameCopy[sizeof(nameCopy) - 1] = '\0';
|
||||
strlcpy(nameCopy, name, sizeof(nameCopy) - 1);
|
||||
|
||||
return file_open_entry_ref(device, inode, nameCopy, omode, true);
|
||||
}
|
||||
@ -2591,12 +2649,10 @@ sys_open_entry_ref(dev_t device, ino_t inode, const char *name, int omode)
|
||||
int
|
||||
sys_open(const char *path, int omode)
|
||||
{
|
||||
char pathCopy[SYS_MAX_PATH_LEN + 1];
|
||||
char pathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
strlcpy(pathBuffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
strncpy(pathCopy, path, SYS_MAX_PATH_LEN);
|
||||
pathCopy[SYS_MAX_PATH_LEN] = 0;
|
||||
|
||||
return file_open(pathCopy, omode, true);
|
||||
return file_open(pathBuffer, omode, true);
|
||||
}
|
||||
|
||||
|
||||
@ -2610,24 +2666,17 @@ sys_open_dir_node_ref(dev_t device, ino_t inode)
|
||||
int
|
||||
sys_open_dir_entry_ref(dev_t device, ino_t inode, const char *name)
|
||||
{
|
||||
char nameCopy[B_FILE_NAME_LENGTH];
|
||||
|
||||
strncpy(nameCopy, name, sizeof(nameCopy) - 1);
|
||||
nameCopy[sizeof(nameCopy) - 1] = '\0';
|
||||
|
||||
return dir_open_entry_ref(device, inode, nameCopy, true);
|
||||
return dir_open_entry_ref(device, inode, name, true);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sys_open_dir(const char *path)
|
||||
{
|
||||
char buffer[SYS_MAX_PATH_LEN + 1];
|
||||
char pathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
strlcpy(pathBuffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
strncpy(buffer, path, SYS_MAX_PATH_LEN);
|
||||
buffer[SYS_MAX_PATH_LEN] = 0;
|
||||
|
||||
return dir_open(buffer, true);
|
||||
return dir_open(pathBuffer, true);
|
||||
}
|
||||
|
||||
|
||||
@ -2641,13 +2690,7 @@ sys_fsync(int fd)
|
||||
int
|
||||
sys_create_entry_ref(dev_t device, ino_t inode, const char *name, int omode, int perms)
|
||||
{
|
||||
char nameCopy[B_FILE_NAME_LENGTH];
|
||||
int status;
|
||||
|
||||
strncpy(nameCopy, name, sizeof(nameCopy) - 1);
|
||||
nameCopy[sizeof(nameCopy) - 1] = '\0';
|
||||
|
||||
return file_create_entry_ref(device, inode, nameCopy, omode, perms, true);
|
||||
return file_create_entry_ref(device, inode, name, omode, perms, true);
|
||||
}
|
||||
|
||||
|
||||
@ -2655,9 +2698,7 @@ int
|
||||
sys_create(const char *path, int omode, int perms)
|
||||
{
|
||||
char buffer[SYS_MAX_PATH_LEN + 1];
|
||||
|
||||
strncpy(buffer, path, SYS_MAX_PATH_LEN);
|
||||
buffer[SYS_MAX_PATH_LEN] = '\0';
|
||||
strlcpy(buffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
return file_create(buffer, omode, perms, true);
|
||||
}
|
||||
@ -2666,135 +2707,134 @@ sys_create(const char *path, int omode, int perms)
|
||||
int
|
||||
sys_create_dir_entry_ref(dev_t device, ino_t inode, const char *name, int perms)
|
||||
{
|
||||
char nameCopy[B_FILE_NAME_LENGTH];
|
||||
|
||||
strncpy(nameCopy, name, sizeof(nameCopy) - 1);
|
||||
nameCopy[sizeof(nameCopy) - 1] = '\0';
|
||||
|
||||
return dir_create_entry_ref(device, inode, nameCopy, perms, true);
|
||||
return dir_create_entry_ref(device, inode, name, perms, true);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sys_create_dir(const char *path, int perms)
|
||||
{
|
||||
char buffer[SYS_MAX_PATH_LEN + 1];
|
||||
char pathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
strlcpy(pathBuffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
strncpy(buffer, path, SYS_MAX_PATH_LEN);
|
||||
buffer[SYS_MAX_PATH_LEN] = 0;
|
||||
return dir_create(pathBuffer, perms, true);
|
||||
}
|
||||
|
||||
return dir_create(buffer, perms, true);
|
||||
|
||||
int
|
||||
sys_remove_dir(const char *path)
|
||||
{
|
||||
char pathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
strlcpy(pathBuffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
return dir_remove(pathBuffer, true);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sys_read_link(const char *path, char *buffer, size_t bufferSize)
|
||||
{
|
||||
char pathCopy[SYS_MAX_PATH_LEN + 1];
|
||||
int status;
|
||||
char pathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
strlcpy(pathBuffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
strncpy(pathCopy, path, SYS_MAX_PATH_LEN);
|
||||
pathCopy[SYS_MAX_PATH_LEN] = '\0';
|
||||
|
||||
return common_read_link(pathCopy, buffer, bufferSize, true);
|
||||
return common_read_link(pathBuffer, buffer, bufferSize, true);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sys_write_link(const char *path, const char *toPath)
|
||||
{
|
||||
char pathCopy[SYS_MAX_PATH_LEN + 1];
|
||||
char toPathCopy[SYS_MAX_PATH_LEN + 1];
|
||||
char pathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
char toPathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
int status;
|
||||
|
||||
strncpy(pathCopy, path, SYS_MAX_PATH_LEN);
|
||||
pathCopy[SYS_MAX_PATH_LEN] = '\0';
|
||||
strlcpy(pathBuffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
strlcpy(toPathBuffer, toPath, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
strncpy(toPathCopy, toPath, SYS_MAX_PATH_LEN);
|
||||
toPathCopy[SYS_MAX_PATH_LEN] = '\0';
|
||||
|
||||
status = check_path(toPathCopy);
|
||||
status = check_path(toPathBuffer);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return common_write_link(pathCopy, toPathCopy, true);
|
||||
return common_write_link(pathBuffer, toPathBuffer, true);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sys_create_symlink(const char *userPath, const char *userToPath, int mode)
|
||||
sys_create_symlink(const char *path, const char *toPath, int mode)
|
||||
{
|
||||
char path[SYS_MAX_PATH_LEN + 1];
|
||||
char toPath[SYS_MAX_PATH_LEN + 1];
|
||||
char pathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
char toPathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
int status;
|
||||
|
||||
strncpy(path, userPath, SYS_MAX_PATH_LEN);
|
||||
path[SYS_MAX_PATH_LEN] = '\0';
|
||||
|
||||
strncpy(toPath, userToPath, SYS_MAX_PATH_LEN);
|
||||
toPath[SYS_MAX_PATH_LEN] = '\0';
|
||||
strlcpy(pathBuffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
strlcpy(toPathBuffer, toPath, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
status = check_path(toPath);
|
||||
status = check_path(toPathBuffer);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return common_create_symlink(path, toPath, mode, true);
|
||||
return common_create_symlink(pathBuffer, toPathBuffer, mode, true);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sys_create_link(const char *path, const char *toPath)
|
||||
{
|
||||
char pathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
char toPathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
|
||||
strlcpy(pathBuffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
strlcpy(toPathBuffer, toPath, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
return common_create_link(pathBuffer, toPathBuffer, true);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sys_unlink(const char *path)
|
||||
{
|
||||
char buf[SYS_MAX_PATH_LEN + 1];
|
||||
char pathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
strlcpy(pathBuffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
strncpy(buf, path, SYS_MAX_PATH_LEN);
|
||||
buf[SYS_MAX_PATH_LEN] = 0;
|
||||
|
||||
return common_unlink(buf, true);
|
||||
return common_unlink(pathBuffer, true);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sys_rename(const char *oldpath, const char *newpath)
|
||||
sys_rename(const char *oldPath, const char *newPath)
|
||||
{
|
||||
char buf1[SYS_MAX_PATH_LEN + 1];
|
||||
char buf2[SYS_MAX_PATH_LEN + 1];
|
||||
char oldPathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
char newPathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
|
||||
strncpy(buf1, oldpath, SYS_MAX_PATH_LEN);
|
||||
buf1[SYS_MAX_PATH_LEN] = 0;
|
||||
strlcpy(oldPathBuffer, oldPath, SYS_MAX_PATH_LEN - 1);
|
||||
strlcpy(newPathBuffer, newPath, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
strncpy(buf2, newpath, SYS_MAX_PATH_LEN);
|
||||
buf2[SYS_MAX_PATH_LEN] = 0;
|
||||
|
||||
return common_rename(buf1, buf2, true);
|
||||
return common_rename(oldPathBuffer, newPathBuffer, true);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sys_access(const char *path, int mode)
|
||||
{
|
||||
char pathCopy[SYS_MAX_PATH_LEN + 1];
|
||||
int status;
|
||||
char pathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
strlcpy(pathBuffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
strlcpy(pathCopy, path, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
return common_access(pathCopy, mode, true);
|
||||
return common_access(pathBuffer, mode, true);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sys_read_stat(const char *path, bool traverseLeafLink, struct stat *stat)
|
||||
{
|
||||
char buffer[SYS_MAX_PATH_LEN + 1];
|
||||
char pathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
struct vnode *vnode;
|
||||
int status;
|
||||
|
||||
strncpy(buffer, path, SYS_MAX_PATH_LEN);
|
||||
buffer[SYS_MAX_PATH_LEN] = 0;
|
||||
strlcpy(pathBuffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
FUNCTION(("sys_read_stat: path '%s', stat %p,\n", path, stat));
|
||||
|
||||
status = path_to_vnode(buffer, traverseLeafLink, &vnode, true);
|
||||
status = path_to_vnode(pathBuffer, traverseLeafLink, &vnode, true);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
@ -2806,29 +2846,27 @@ sys_read_stat(const char *path, bool traverseLeafLink, struct stat *stat)
|
||||
|
||||
|
||||
int
|
||||
sys_write_stat(int fd, const char *_path, bool traverseLeafLink, struct stat *stat, int statMask)
|
||||
sys_write_stat(int fd, const char *path, bool traverseLeafLink, struct stat *stat, int statMask)
|
||||
{
|
||||
char path[SYS_MAX_PATH_LEN + 1];
|
||||
char pathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
|
||||
if (fd == -1) {
|
||||
strncpy(path, _path, SYS_MAX_PATH_LEN - 1);
|
||||
path[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
}
|
||||
if (fd == -1)
|
||||
strlcpy(pathBuffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
return common_write_stat(fd, path, traverseLeafLink, stat, statMask, true);
|
||||
return common_write_stat(fd, pathBuffer, traverseLeafLink, stat, statMask, true);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sys_getcwd(char *buffer, size_t size)
|
||||
{
|
||||
char path[SYS_MAX_PATH_LEN + 1];
|
||||
char path[SYS_MAX_PATH_LEN];
|
||||
int status;
|
||||
|
||||
PRINT(("sys_getcwd: buf %p, %ld\n", buffer, size));
|
||||
|
||||
// Call vfs to get current working directory
|
||||
status = get_cwd(path, SYS_MAX_PATH_LEN - 1,true);
|
||||
status = get_cwd(path, SYS_MAX_PATH_LEN - 1, true);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
@ -2840,21 +2878,12 @@ sys_getcwd(char *buffer, size_t size)
|
||||
|
||||
|
||||
int
|
||||
sys_setcwd(int fd, const char *_path)
|
||||
sys_setcwd(int fd, const char *path)
|
||||
{
|
||||
char path[SYS_MAX_PATH_LEN];
|
||||
char pathBuffer[SYS_MAX_PATH_LEN + 1];
|
||||
strlcpy(pathBuffer, path, SYS_MAX_PATH_LEN - 1);
|
||||
|
||||
PRINT(("sys_setcwd: path = %s\n", _path));
|
||||
|
||||
if (_path != NULL) {
|
||||
// Copy new path to kernel space
|
||||
strncpy(path, _path, SYS_MAX_PATH_LEN - 1);
|
||||
path[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
} else
|
||||
path[0] = '\0';
|
||||
|
||||
// Call vfs to set new working directory
|
||||
return set_cwd(fd, path, true);
|
||||
return set_cwd(fd, pathBuffer, true);
|
||||
}
|
||||
|
||||
|
||||
@ -2875,23 +2904,23 @@ user_mount(const char *upath, const char *udevice, const char *ufs_name, void *a
|
||||
|| !CHECK_USER_ADDRESS(udevice))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
rc = user_strncpy(path, upath, SYS_MAX_PATH_LEN);
|
||||
rc = user_strncpy(path, upath, SYS_MAX_PATH_LEN - 1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
path[SYS_MAX_PATH_LEN] = 0;
|
||||
path[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
rc = user_strncpy(fs_name, ufs_name, SYS_MAX_OS_NAME_LEN);
|
||||
rc = user_strncpy(fs_name, ufs_name, SYS_MAX_OS_NAME_LEN - 1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
fs_name[SYS_MAX_OS_NAME_LEN] = 0;
|
||||
fs_name[SYS_MAX_OS_NAME_LEN - 1] = '\0';
|
||||
|
||||
if (udevice) {
|
||||
rc = user_strncpy(device, udevice, SYS_MAX_PATH_LEN);
|
||||
rc = user_strncpy(device, udevice, SYS_MAX_PATH_LEN - 1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
device[SYS_MAX_PATH_LEN] = 0;
|
||||
device[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
} else
|
||||
device[0] = 0;
|
||||
device[0] = '\0';
|
||||
|
||||
return fs_mount(path, device, fs_name, args, false);
|
||||
}
|
||||
@ -2901,12 +2930,12 @@ int
|
||||
user_unmount(const char *upath)
|
||||
{
|
||||
char path[SYS_MAX_PATH_LEN + 1];
|
||||
int rc;
|
||||
int status;
|
||||
|
||||
rc = user_strncpy(path, upath, SYS_MAX_PATH_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
path[SYS_MAX_PATH_LEN] = 0;
|
||||
status = user_strncpy(path, upath, SYS_MAX_PATH_LEN - 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
path[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
return fs_unmount(path, false);
|
||||
}
|
||||
@ -2920,15 +2949,15 @@ user_sync(void)
|
||||
|
||||
|
||||
int
|
||||
user_open_entry_ref(dev_t device, ino_t inode, const char *uname, int omode)
|
||||
user_open_entry_ref(dev_t device, ino_t inode, const char *userName, int omode)
|
||||
{
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
int status;
|
||||
|
||||
if (!CHECK_USER_ADDRESS(uname))
|
||||
if (!CHECK_USER_ADDRESS(userName))
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
|
||||
status = user_strncpy(name, uname, sizeof(name) - 1);
|
||||
status = user_strncpy(name, userName, sizeof(name) - 1);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
name[sizeof(name) - 1] = '\0';
|
||||
@ -2938,18 +2967,18 @@ user_open_entry_ref(dev_t device, ino_t inode, const char *uname, int omode)
|
||||
|
||||
|
||||
int
|
||||
user_open(const char *upath, int omode)
|
||||
user_open(const char *userPath, int omode)
|
||||
{
|
||||
char path[SYS_MAX_PATH_LEN + 1];
|
||||
int rc;
|
||||
int status;
|
||||
|
||||
if (!CHECK_USER_ADDRESS(upath))
|
||||
if (!CHECK_USER_ADDRESS(userPath))
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
|
||||
rc = user_strncpy(path, upath, sizeof(path));
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
path[sizeof(path)] = 0;
|
||||
status = user_strncpy(path, userPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
path[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
return file_open(path, omode, false);
|
||||
}
|
||||
@ -2981,18 +3010,18 @@ user_open_dir_entry_ref(dev_t device, ino_t inode, const char *uname)
|
||||
|
||||
|
||||
int
|
||||
user_open_dir(const char *upath)
|
||||
user_open_dir(const char *userPath)
|
||||
{
|
||||
char path[SYS_MAX_PATH_LEN + 1];
|
||||
int status;
|
||||
|
||||
if (!CHECK_USER_ADDRESS(upath))
|
||||
if (!CHECK_USER_ADDRESS(userPath))
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
|
||||
status = user_strncpy(path, upath, sizeof(path));
|
||||
status = user_strncpy(path, userPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
path[sizeof(path)] = 0;
|
||||
path[SYS_MAX_PATH_LEN - 1] = 0;
|
||||
|
||||
return dir_open(path, false);
|
||||
}
|
||||
@ -3024,18 +3053,18 @@ user_create_entry_ref(dev_t device, ino_t inode, const char *uname, int omode, i
|
||||
|
||||
|
||||
int
|
||||
user_create(const char *upath, int omode, int perms)
|
||||
user_create(const char *userPath, int omode, int perms)
|
||||
{
|
||||
char path[SYS_MAX_PATH_LEN + 1];
|
||||
int status;
|
||||
|
||||
if ((addr)upath >= KERNEL_BASE && (addr)upath <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
if (!CHECK_USER_ADDRESS(userPath))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
status = user_strncpy(path, upath, SYS_MAX_PATH_LEN);
|
||||
status = user_strncpy(path, userPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
path[SYS_MAX_PATH_LEN] = '\0';
|
||||
path[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
return file_create(path, omode, perms, false);
|
||||
}
|
||||
@ -3048,7 +3077,7 @@ user_create_dir_entry_ref(dev_t device, ino_t inode, const char *uname, int perm
|
||||
int status;
|
||||
|
||||
if (!CHECK_USER_ADDRESS(uname))
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
status = user_strncpy(name, uname, sizeof(name) - 1);
|
||||
if (status < 0)
|
||||
@ -3066,17 +3095,35 @@ user_create_dir(const char *userPath, int perms)
|
||||
int status;
|
||||
|
||||
if (!CHECK_USER_ADDRESS(userPath))
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
status = user_strncpy(path, userPath, SYS_MAX_PATH_LEN);
|
||||
status = user_strncpy(path, userPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
path[SYS_MAX_PATH_LEN] = '\0';
|
||||
path[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
return dir_create(path, perms, false);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
user_remove_dir(const char *userPath)
|
||||
{
|
||||
char path[SYS_MAX_PATH_LEN + 1];
|
||||
int status;
|
||||
|
||||
if (!CHECK_USER_ADDRESS(userPath))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
status = user_strncpy(path, userPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
path[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
return dir_remove(path, false);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
user_read_link(const char *userPath, char *userBuffer, size_t bufferSize)
|
||||
{
|
||||
@ -3088,16 +3135,19 @@ user_read_link(const char *userPath, char *userBuffer, size_t bufferSize)
|
||||
|| !CHECK_USER_ADDRESS(userBuffer))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
status = user_strncpy(path, userPath, SYS_MAX_PATH_LEN);
|
||||
status = user_strncpy(path, userPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
path[SYS_MAX_PATH_LEN] = '\0';
|
||||
path[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
if (bufferSize > SYS_MAX_PATH_LEN)
|
||||
bufferSize = SYS_MAX_PATH_LEN;
|
||||
|
||||
status = common_read_link(path, buffer, bufferSize, false);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return user_strncpy(userBuffer, buffer, SYS_MAX_PATH_LEN);
|
||||
return user_strncpy(userBuffer, buffer, bufferSize);
|
||||
}
|
||||
|
||||
|
||||
@ -3112,15 +3162,15 @@ user_write_link(const char *userPath, const char *userToPath)
|
||||
|| !CHECK_USER_ADDRESS(userToPath))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
status = user_strncpy(path, userPath, SYS_MAX_PATH_LEN);
|
||||
status = user_strncpy(path, userPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
path[SYS_MAX_PATH_LEN] = '\0';
|
||||
path[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
status = user_strncpy(toPath, userToPath, SYS_MAX_PATH_LEN);
|
||||
status = user_strncpy(toPath, userToPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
toPath[SYS_MAX_PATH_LEN] = '\0';
|
||||
toPath[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
status = check_path(toPath);
|
||||
if (status < B_OK)
|
||||
@ -3141,15 +3191,15 @@ user_create_symlink(const char *userPath, const char *userToPath, int mode)
|
||||
|| !CHECK_USER_ADDRESS(userToPath))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
status = user_strncpy(path, userPath, SYS_MAX_PATH_LEN);
|
||||
status = user_strncpy(path, userPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
path[SYS_MAX_PATH_LEN] = '\0';
|
||||
path[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
status = user_strncpy(toPath, userToPath, SYS_MAX_PATH_LEN);
|
||||
status = user_strncpy(toPath, userToPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
toPath[SYS_MAX_PATH_LEN] = '\0';
|
||||
toPath[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
status = check_path(toPath);
|
||||
if (status < B_OK)
|
||||
@ -3159,6 +3209,35 @@ user_create_symlink(const char *userPath, const char *userToPath, int mode)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
user_create_link(const char *userPath, const char *userToPath)
|
||||
{
|
||||
char path[SYS_MAX_PATH_LEN + 1];
|
||||
char toPath[SYS_MAX_PATH_LEN + 1];
|
||||
int status;
|
||||
|
||||
if (!CHECK_USER_ADDRESS(userPath)
|
||||
|| !CHECK_USER_ADDRESS(userToPath))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
status = user_strncpy(path, userPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
path[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
status = user_strncpy(toPath, userToPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
toPath[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
status = check_path(toPath);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return common_create_link(path, toPath, false);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
user_unlink(const char *userPath)
|
||||
{
|
||||
@ -3178,29 +3257,26 @@ user_unlink(const char *userPath)
|
||||
|
||||
|
||||
int
|
||||
user_rename(const char *uoldpath, const char *unewpath)
|
||||
user_rename(const char *userOldPath, const char *userNewPath)
|
||||
{
|
||||
char oldpath[SYS_MAX_PATH_LEN + 1];
|
||||
char newpath[SYS_MAX_PATH_LEN + 1];
|
||||
int rc;
|
||||
char oldPath[SYS_MAX_PATH_LEN + 1];
|
||||
char newPath[SYS_MAX_PATH_LEN + 1];
|
||||
int status;
|
||||
|
||||
if ((addr)uoldpath >= KERNEL_BASE && (addr)uoldpath <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
if (!CHECK_USER_ADDRESS(userOldPath) || !CHECK_USER_ADDRESS(userNewPath))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
if ((addr)unewpath >= KERNEL_BASE && (addr)unewpath <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
status = user_strncpy(oldPath, userOldPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
oldPath[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
rc = user_strncpy(oldpath, uoldpath, SYS_MAX_PATH_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
oldpath[SYS_MAX_PATH_LEN] = 0;
|
||||
status = user_strncpy(newPath, userNewPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
newPath[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
rc = user_strncpy(newpath, unewpath, SYS_MAX_PATH_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
newpath[SYS_MAX_PATH_LEN] = 0;
|
||||
|
||||
return common_rename(oldpath, newpath, false);
|
||||
return common_rename(oldPath, newPath, false);
|
||||
}
|
||||
|
||||
|
||||
@ -3234,10 +3310,10 @@ user_read_stat(const char *userPath, bool traverseLink, struct stat *userStat)
|
||||
|| !CHECK_USER_ADDRESS(userStat))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
rc = user_strncpy(path, userPath, SYS_MAX_PATH_LEN);
|
||||
rc = user_strncpy(path, userPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
path[SYS_MAX_PATH_LEN] = 0;
|
||||
path[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
|
||||
FUNCTION(("user_read_stat(path = %s, traverseLeafLink = %d)\n", path, traverseLink));
|
||||
|
||||
@ -3284,24 +3360,26 @@ user_write_stat(int fd, const char *userPath, bool traverseLeafLink, struct stat
|
||||
|
||||
|
||||
int
|
||||
user_getcwd(char *buffer, size_t size)
|
||||
user_getcwd(char *userBuffer, size_t size)
|
||||
{
|
||||
char path[SYS_MAX_PATH_LEN];
|
||||
char buffer[SYS_MAX_PATH_LEN];
|
||||
int status;
|
||||
|
||||
PRINT(("user_getcwd: buf %p, %ld\n", buffer, size));
|
||||
PRINT(("user_getcwd: buf %p, %ld\n", userBuffer, size));
|
||||
|
||||
// Check if userspace address is inside "shared" kernel space
|
||||
if ((addr)buffer >= KERNEL_BASE && (addr)buffer <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
if (!CHECK_USER_ADDRESS(userBuffer))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
if (size > SYS_MAX_PATH_LEN)
|
||||
size = SYS_MAX_PATH_LEN;
|
||||
|
||||
// Call vfs to get current working directory
|
||||
status = get_cwd(path, sizeof(path), false);
|
||||
status = get_cwd(buffer, size, false);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
// Copy back the result
|
||||
if (user_strncpy(buffer, path, size) < 0)
|
||||
if (user_strncpy(userBuffer, buffer, size) < 0)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
|
||||
return status;
|
||||
@ -3316,15 +3394,13 @@ user_setcwd(int fd, const char *userPath)
|
||||
|
||||
PRINT(("user_setcwd: path = %p\n", userPath));
|
||||
|
||||
if (userPath != NULL) {
|
||||
if (fd == -1) {
|
||||
if (!CHECK_USER_ADDRESS(userPath))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
// Copy new path to kernel space
|
||||
rc = user_strncpy(path, userPath, SYS_MAX_PATH_LEN - 1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
path[SYS_MAX_PATH_LEN - 1] = '\0';
|
||||
} else
|
||||
path[0] = '\0';
|
||||
|
@ -114,9 +114,15 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re
|
||||
case SYSCALL_CREATE_SYMLINK:
|
||||
*call_ret = user_create_symlink((const char *)arg0, (const char *)arg1, (int)arg2);
|
||||
break;
|
||||
case SYSCALL_CREATE_LINK:
|
||||
*call_ret = user_create_link((const char *)arg0, (const char *)arg1);
|
||||
break;
|
||||
case SYSCALL_READ_LINK:
|
||||
*call_ret = user_read_link((const char *)arg0, (char *)arg1, (size_t)arg2);
|
||||
break;
|
||||
case SYSCALL_REMOVE_DIR:
|
||||
*call_ret = user_remove_dir((const char *)arg0);
|
||||
break;
|
||||
case SYSCALL_UNLINK:
|
||||
*call_ret = user_unlink((const char *)arg0);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user