* Introduced dedicated syscalls for the deprecated BeOS fs_attr API. Before,
each attribute access needed 3 syscalls, now only one as it should. * Renamed the new Haiku call fs_open_attr() to fs_fopen_attr(), and added a new function fs_open_attr() that takes a path (same semantics as the fs_[f]open_attr_dir() functions already present in BeOS). * Merged former _kern_open_attr(), and _kern_create_attr() into one syscall. * Cleaned up vfs.h. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31881 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+14
-11
@@ -1,7 +1,7 @@
|
||||
/* File System attributes
|
||||
**
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2004-2009, Haiku Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _FS_ATTR_H
|
||||
#define _FS_ATTR_H
|
||||
|
||||
@@ -20,15 +20,18 @@ typedef struct attr_info {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern ssize_t fs_read_attr(int fd, const char *attribute, uint32 type, off_t pos, void *buffer, size_t readBytes);
|
||||
extern ssize_t fs_write_attr(int fd, const char *attribute, uint32 type, off_t pos, const void *buffer, size_t readBytes);
|
||||
extern ssize_t fs_read_attr(int fd, const char *attribute, uint32 type,
|
||||
off_t pos, void *buffer, size_t readBytes);
|
||||
extern ssize_t fs_write_attr(int fd, const char *attribute, uint32 type,
|
||||
off_t pos, const void *buffer, size_t readBytes);
|
||||
extern int fs_remove_attr(int fd, const char *attribute);
|
||||
extern int fs_stat_attr(int fd, const char *attribute, struct attr_info *attrInfo);
|
||||
extern int fs_stat_attr(int fd, const char *attribute,
|
||||
struct attr_info *attrInfo);
|
||||
|
||||
// ToDo: the following three functions are not part of the R5 API, and
|
||||
// are only preliminary - they may change or be removed at any point
|
||||
//extern int fs_open_attr(const char *path, const char *attribute, uint32 type, int openMode);
|
||||
extern int fs_open_attr(int fd, const char *attribute, uint32 type, int openMode);
|
||||
extern int fs_open_attr(const char *path, const char *attribute,
|
||||
uint32 type, int openMode);
|
||||
extern int fs_fopen_attr(int fd, const char *attribute, uint32 type,
|
||||
int openMode);
|
||||
extern int fs_close_attr(int fd);
|
||||
|
||||
extern DIR *fs_open_attr_dir(const char *path);
|
||||
|
||||
+187
-171
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Copyright 2002-2009, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
@@ -31,10 +31,12 @@
|
||||
|
||||
#define B_UNMOUNT_BUSY_PARTITION 0x80000000
|
||||
|
||||
struct attr_info;
|
||||
struct file_descriptor;
|
||||
struct kernel_args;
|
||||
struct net_stat;
|
||||
struct pollfd;
|
||||
struct rlimit;
|
||||
struct selectsync;
|
||||
struct select_info;
|
||||
struct VMCache;
|
||||
@@ -67,191 +69,206 @@ typedef struct io_context {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
status_t vfs_init(struct kernel_args *args);
|
||||
status_t vfs_bootstrap_file_systems(void);
|
||||
void vfs_mount_boot_file_system(struct kernel_args *args);
|
||||
void vfs_exec_io_context(io_context *context);
|
||||
status_t vfs_init(struct kernel_args *args);
|
||||
status_t vfs_bootstrap_file_systems(void);
|
||||
void vfs_mount_boot_file_system(struct kernel_args *args);
|
||||
void vfs_exec_io_context(io_context *context);
|
||||
io_context *vfs_new_io_context(io_context *parentContext);
|
||||
void vfs_get_io_context(io_context *context);
|
||||
void vfs_put_io_context(io_context *context);
|
||||
void vfs_get_io_context(io_context *context);
|
||||
void vfs_put_io_context(io_context *context);
|
||||
|
||||
struct rlimit;
|
||||
int vfs_getrlimit(int resource, struct rlimit * rlp);
|
||||
int vfs_setrlimit(int resource, const struct rlimit * rlp);
|
||||
int vfs_getrlimit(int resource, struct rlimit *rlp);
|
||||
int vfs_setrlimit(int resource, const struct rlimit *rlp);
|
||||
|
||||
/* calls needed by the VM for paging and by the file cache */
|
||||
int vfs_get_vnode_from_fd(int fd, bool kernel, struct vnode **_vnode);
|
||||
status_t vfs_get_vnode_from_path(const char *path, bool kernel,
|
||||
struct vnode **_vnode);
|
||||
status_t vfs_get_vnode(dev_t mountID, ino_t vnodeID, bool canWait,
|
||||
struct vnode **_vnode);
|
||||
status_t vfs_entry_ref_to_vnode(dev_t mountID, ino_t directoryID,
|
||||
const char *name, struct vnode **_vnode);
|
||||
void vfs_vnode_to_node_ref(struct vnode *vnode, dev_t *_mountID,
|
||||
ino_t *_vnodeID);
|
||||
int vfs_get_vnode_from_fd(int fd, bool kernel, struct vnode **_vnode);
|
||||
status_t vfs_get_vnode_from_path(const char *path, bool kernel,
|
||||
struct vnode **_vnode);
|
||||
status_t vfs_get_vnode(dev_t mountID, ino_t vnodeID, bool canWait,
|
||||
struct vnode **_vnode);
|
||||
status_t vfs_entry_ref_to_vnode(dev_t mountID, ino_t directoryID,
|
||||
const char *name, struct vnode **_vnode);
|
||||
void vfs_vnode_to_node_ref(struct vnode *vnode, dev_t *_mountID,
|
||||
ino_t *_vnodeID);
|
||||
|
||||
status_t vfs_lookup_vnode(dev_t mountID, ino_t vnodeID, struct vnode **_vnode);
|
||||
void vfs_put_vnode(struct vnode *vnode);
|
||||
void vfs_acquire_vnode(struct vnode *vnode);
|
||||
status_t vfs_get_cookie_from_fd(int fd, void **_cookie);
|
||||
bool vfs_can_page(struct vnode *vnode, void *cookie);
|
||||
status_t vfs_read_pages(struct vnode *vnode, void *cookie, off_t pos,
|
||||
const iovec *vecs, size_t count, uint32 flags, size_t *_numBytes);
|
||||
status_t vfs_write_pages(struct vnode *vnode, void *cookie, off_t pos,
|
||||
const iovec *vecs, size_t count, uint32 flags, size_t *_numBytes);
|
||||
status_t vfs_vnode_io(struct vnode* vnode, void* cookie, io_request* request);
|
||||
status_t vfs_synchronous_io(io_request* request,
|
||||
status_t (*doIO)(void* cookie, off_t offset, void* buffer,
|
||||
status_t vfs_lookup_vnode(dev_t mountID, ino_t vnodeID,
|
||||
struct vnode **_vnode);
|
||||
void vfs_put_vnode(struct vnode *vnode);
|
||||
void vfs_acquire_vnode(struct vnode *vnode);
|
||||
status_t vfs_get_cookie_from_fd(int fd, void **_cookie);
|
||||
bool vfs_can_page(struct vnode *vnode, void *cookie);
|
||||
status_t vfs_read_pages(struct vnode *vnode, void *cookie, off_t pos,
|
||||
const iovec *vecs, size_t count, uint32 flags,
|
||||
size_t *_numBytes);
|
||||
status_t vfs_write_pages(struct vnode *vnode, void *cookie, off_t pos,
|
||||
const iovec *vecs, size_t count, uint32 flags,
|
||||
size_t *_numBytes);
|
||||
status_t vfs_vnode_io(struct vnode* vnode, void* cookie,
|
||||
io_request* request);
|
||||
status_t vfs_synchronous_io(io_request* request,
|
||||
status_t (*doIO)(void* cookie, off_t offset, void* buffer,
|
||||
size_t* length),
|
||||
void* cookie);
|
||||
status_t vfs_get_vnode_cache(struct vnode *vnode, struct VMCache **_cache,
|
||||
bool allocate);
|
||||
status_t vfs_get_file_map(struct vnode *vnode, off_t offset, size_t size,
|
||||
struct file_io_vec *vecs, size_t *_count);
|
||||
status_t vfs_get_fs_node_from_path(fs_volume *volume, const char *path,
|
||||
bool kernel, void **_node);
|
||||
status_t vfs_stat_vnode(struct vnode *vnode, struct stat *stat);
|
||||
status_t vfs_stat_node_ref(dev_t device, ino_t inode, 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);
|
||||
status_t vfs_disconnect_vnode(dev_t mountID, ino_t vnodeID);
|
||||
void vfs_free_unused_vnodes(int32 level);
|
||||
status_t vfs_get_vnode_cache(struct vnode *vnode, struct VMCache **_cache,
|
||||
bool allocate);
|
||||
status_t vfs_get_file_map(struct vnode *vnode, off_t offset, size_t size,
|
||||
struct file_io_vec *vecs, size_t *_count);
|
||||
status_t vfs_get_fs_node_from_path(fs_volume *volume, const char *path,
|
||||
bool kernel, void **_node);
|
||||
status_t vfs_stat_vnode(struct vnode *vnode, struct stat *stat);
|
||||
status_t vfs_stat_node_ref(dev_t device, ino_t inode, 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);
|
||||
status_t vfs_disconnect_vnode(dev_t mountID, ino_t vnodeID);
|
||||
void vfs_free_unused_vnodes(int32 level);
|
||||
|
||||
status_t vfs_read_stat(int fd, const char *path, bool traverseLeafLink,
|
||||
struct stat *stat, bool kernel);
|
||||
status_t vfs_read_stat(int fd, const char *path, bool traverseLeafLink,
|
||||
struct stat *stat, bool kernel);
|
||||
|
||||
/* special module convenience call */
|
||||
status_t vfs_get_module_path(const char *basePath, const char *moduleName,
|
||||
char *pathBuffer, size_t bufferSize);
|
||||
status_t vfs_get_module_path(const char *basePath, const char *moduleName,
|
||||
char *pathBuffer, size_t bufferSize);
|
||||
|
||||
/* service call for whoever needs a normalized path */
|
||||
status_t vfs_normalize_path(const char *path, char *buffer, size_t bufferSize,
|
||||
bool traverseLink, bool kernel);
|
||||
status_t vfs_normalize_path(const char *path, char *buffer,
|
||||
size_t bufferSize, bool traverseLink, bool kernel);
|
||||
|
||||
/* service call for whoever wants to create a special node */
|
||||
status_t vfs_create_special_node(const char *path, fs_vnode *subVnode,
|
||||
mode_t mode, uint32 flags, bool kernel, fs_vnode *_superVnode,
|
||||
struct vnode **_createdVnode);
|
||||
status_t vfs_create_special_node(const char *path, fs_vnode *subVnode,
|
||||
mode_t mode, uint32 flags, bool kernel, fs_vnode *_superVnode,
|
||||
struct vnode **_createdVnode);
|
||||
|
||||
/* service call for the node monitor */
|
||||
status_t resolve_mount_point_to_volume_root(dev_t mountID, ino_t nodeID,
|
||||
dev_t *resolvedMountID, ino_t *resolvedNodeID);
|
||||
status_t resolve_mount_point_to_volume_root(dev_t mountID, ino_t nodeID,
|
||||
dev_t *resolvedMountID, ino_t *resolvedNodeID);
|
||||
|
||||
/* calls the syscall dispatcher should use for user file I/O */
|
||||
dev_t _user_mount(const char *path, const char *device, const char *fs_name,
|
||||
uint32 flags, const char *args, size_t argsLength);
|
||||
status_t _user_unmount(const char *path, uint32 flags);
|
||||
status_t _user_read_fs_info(dev_t device, struct fs_info *info);
|
||||
status_t _user_write_fs_info(dev_t device, const struct fs_info *info, int mask);
|
||||
dev_t _user_next_device(int32 *_cookie);
|
||||
status_t _user_sync(void);
|
||||
status_t _user_get_next_fd_info(team_id team, uint32 *cookie, struct fd_info *info,
|
||||
size_t infoSize);
|
||||
status_t _user_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
|
||||
char *userPath, size_t pathLength);
|
||||
status_t _user_normalize_path(const char* userPath, bool traverseLink,
|
||||
char* buffer);
|
||||
int _user_open_entry_ref(dev_t device, ino_t inode, const char *name, int openMode, int perms);
|
||||
int _user_open(int fd, const char *path, int openMode, int perms);
|
||||
int _user_open_dir_node_ref(dev_t device, ino_t inode);
|
||||
int _user_open_dir_entry_ref(dev_t device, ino_t inode, const char *uname);
|
||||
int _user_open_dir(int fd, const char *path);
|
||||
int _user_open_parent_dir(int fd, char *name, size_t nameLength);
|
||||
status_t _user_fcntl(int fd, int op, uint32 argument);
|
||||
status_t _user_fsync(int fd);
|
||||
status_t _user_flock(int fd, int op);
|
||||
status_t _user_read_stat(int fd, const char *path, bool traverseLink,
|
||||
struct stat *stat, size_t statSize);
|
||||
status_t _user_write_stat(int fd, const char *path, bool traverseLink,
|
||||
const struct stat *stat, size_t statSize, int statMask);
|
||||
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(int fd, const char *path, int perms);
|
||||
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_write_link(const char *path, const char *toPath);
|
||||
status_t _user_create_symlink(int fd, const char *path, const char *toPath,
|
||||
int mode);
|
||||
status_t _user_create_link(const char *path, const char *toPath);
|
||||
status_t _user_unlink(int fd, const char *path);
|
||||
status_t _user_rename(int oldFD, const char *oldpath, int newFD,
|
||||
const char *newpath);
|
||||
status_t _user_create_fifo(const char *path, mode_t perms);
|
||||
status_t _user_create_pipe(int *fds);
|
||||
status_t _user_access(const char *path, int mode);
|
||||
ssize_t _user_select(int numfds, fd_set *readSet, fd_set *writeSet, fd_set *errorSet,
|
||||
bigtime_t timeout, const sigset_t *sigMask);
|
||||
ssize_t _user_poll(struct pollfd *fds, int numfds, bigtime_t timeout);
|
||||
int _user_open_attr_dir(int fd, const char *path);
|
||||
int _user_create_attr(int fd, const char *name, uint32 type, int openMode);
|
||||
int _user_open_attr(int fd, const char *name, int openMode);
|
||||
status_t _user_remove_attr(int fd, const char *name);
|
||||
status_t _user_rename_attr(int fromFile, const char *fromName, int toFile, const char *toName);
|
||||
int _user_open_index_dir(dev_t device);
|
||||
status_t _user_create_index(dev_t device, const char *name, uint32 type, uint32 flags);
|
||||
status_t _user_read_index_stat(dev_t device, const char *name, struct stat *stat);
|
||||
status_t _user_remove_index(dev_t device, const char *name);
|
||||
status_t _user_getcwd(char *buffer, size_t size);
|
||||
status_t _user_setcwd(int fd, const char *path);
|
||||
status_t _user_change_root(const char *path);
|
||||
int _user_open_query(dev_t device, const char *query, size_t queryLength, uint32 flags,
|
||||
port_id port, int32 token);
|
||||
dev_t _user_mount(const char *path, const char *device,
|
||||
const char *fs_name, uint32 flags, const char *args,
|
||||
size_t argsLength);
|
||||
status_t _user_unmount(const char *path, uint32 flags);
|
||||
status_t _user_read_fs_info(dev_t device, struct fs_info *info);
|
||||
status_t _user_write_fs_info(dev_t device, const struct fs_info *info,
|
||||
int mask);
|
||||
dev_t _user_next_device(int32 *_cookie);
|
||||
status_t _user_sync(void);
|
||||
status_t _user_get_next_fd_info(team_id team, uint32 *cookie,
|
||||
struct fd_info *info, size_t infoSize);
|
||||
status_t _user_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
|
||||
char *userPath, size_t pathLength);
|
||||
status_t _user_normalize_path(const char* userPath, bool traverseLink,
|
||||
char* buffer);
|
||||
int _user_open_entry_ref(dev_t device, ino_t inode, const char *name,
|
||||
int openMode, int perms);
|
||||
int _user_open(int fd, const char *path, int openMode, int perms);
|
||||
int _user_open_dir_node_ref(dev_t device, ino_t inode);
|
||||
int _user_open_dir_entry_ref(dev_t device, ino_t inode,
|
||||
const char *name);
|
||||
int _user_open_dir(int fd, const char *path);
|
||||
int _user_open_parent_dir(int fd, char *name, size_t nameLength);
|
||||
status_t _user_fcntl(int fd, int op, uint32 argument);
|
||||
status_t _user_fsync(int fd);
|
||||
status_t _user_flock(int fd, int op);
|
||||
status_t _user_read_stat(int fd, const char *path, bool traverseLink,
|
||||
struct stat *stat, size_t statSize);
|
||||
status_t _user_write_stat(int fd, const char *path, bool traverseLink,
|
||||
const struct stat *stat, size_t statSize, int statMask);
|
||||
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(int fd, const char *path, int perms);
|
||||
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_write_link(const char *path, const char *toPath);
|
||||
status_t _user_create_symlink(int fd, const char *path, const char *toPath,
|
||||
int mode);
|
||||
status_t _user_create_link(const char *path, const char *toPath);
|
||||
status_t _user_unlink(int fd, const char *path);
|
||||
status_t _user_rename(int oldFD, const char *oldpath, int newFD,
|
||||
const char *newpath);
|
||||
status_t _user_create_fifo(const char *path, mode_t perms);
|
||||
status_t _user_create_pipe(int *fds);
|
||||
status_t _user_access(const char *path, int mode);
|
||||
ssize_t _user_select(int numfds, fd_set *readSet, fd_set *writeSet,
|
||||
fd_set *errorSet, bigtime_t timeout, const sigset_t *sigMask);
|
||||
ssize_t _user_poll(struct pollfd *fds, int numfds, bigtime_t timeout);
|
||||
int _user_open_attr_dir(int fd, const char *path);
|
||||
ssize_t _user_read_attr(int fd, const char *attribute, off_t pos,
|
||||
void *buffer, size_t readBytes);
|
||||
ssize_t _user_write_attr(int fd, const char *attribute, uint32 type,
|
||||
off_t pos, const void *buffer, size_t readBytes);
|
||||
status_t _user_stat_attr(int fd, const char *attribute,
|
||||
struct attr_info *attrInfo);
|
||||
int _user_open_attr(int fd, const char* path, const char *name,
|
||||
uint32 type, int openMode);
|
||||
status_t _user_remove_attr(int fd, const char *name);
|
||||
status_t _user_rename_attr(int fromFile, const char *fromName, int toFile,
|
||||
const char *toName);
|
||||
int _user_open_index_dir(dev_t device);
|
||||
status_t _user_create_index(dev_t device, const char *name, uint32 type,
|
||||
uint32 flags);
|
||||
status_t _user_read_index_stat(dev_t device, const char *name,
|
||||
struct stat *stat);
|
||||
status_t _user_remove_index(dev_t device, const char *name);
|
||||
status_t _user_getcwd(char *buffer, size_t size);
|
||||
status_t _user_setcwd(int fd, const char *path);
|
||||
status_t _user_change_root(const char *path);
|
||||
int _user_open_query(dev_t device, const char *query,
|
||||
size_t queryLength, uint32 flags, port_id port, int32 token);
|
||||
|
||||
/* fd user prototypes (implementation located in fd.cpp) */
|
||||
extern ssize_t _user_read(int fd, off_t pos, void *buffer, size_t bufferSize);
|
||||
extern ssize_t _user_readv(int fd, off_t pos, const iovec *vecs, size_t count);
|
||||
extern ssize_t _user_write(int fd, off_t pos, const void *buffer, size_t bufferSize);
|
||||
extern ssize_t _user_writev(int fd, off_t pos, const iovec *vecs, size_t count);
|
||||
extern status_t _user_ioctl(int fd, ulong cmd, void *data, size_t length);
|
||||
extern ssize_t _user_read_dir(int fd, struct dirent *buffer, size_t bufferSize, uint32 maxCount);
|
||||
extern status_t _user_rewind_dir(int fd);
|
||||
extern status_t _user_close(int fd);
|
||||
extern int _user_dup(int fd);
|
||||
extern int _user_dup2(int ofd, int nfd);
|
||||
extern status_t _user_lock_node(int fd);
|
||||
extern status_t _user_unlock_node(int fd);
|
||||
ssize_t _user_read(int fd, off_t pos, void *buffer, size_t bufferSize);
|
||||
ssize_t _user_readv(int fd, off_t pos, const iovec *vecs, size_t count);
|
||||
ssize_t _user_write(int fd, off_t pos, const void *buffer,
|
||||
size_t bufferSize);
|
||||
ssize_t _user_writev(int fd, off_t pos, const iovec *vecs, size_t count);
|
||||
status_t _user_ioctl(int fd, ulong cmd, void *data, size_t length);
|
||||
ssize_t _user_read_dir(int fd, struct dirent *buffer, size_t bufferSize,
|
||||
uint32 maxCount);
|
||||
status_t _user_rewind_dir(int fd);
|
||||
status_t _user_close(int fd);
|
||||
int _user_dup(int fd);
|
||||
int _user_dup2(int ofd, int nfd);
|
||||
status_t _user_lock_node(int fd);
|
||||
status_t _user_unlock_node(int fd);
|
||||
|
||||
/* socket user prototypes (implementation in socket.cpp) */
|
||||
extern int _user_socket(int family, int type, int protocol);
|
||||
extern status_t _user_bind(int socket, const struct sockaddr *address,
|
||||
socklen_t addressLength);
|
||||
extern status_t _user_shutdown_socket(int socket, int how);
|
||||
extern status_t _user_connect(int socket, const struct sockaddr *address,
|
||||
socklen_t addressLength);
|
||||
extern status_t _user_listen(int socket, int backlog);
|
||||
extern int _user_accept(int socket, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
extern ssize_t _user_recv(int socket, void *data, size_t length,
|
||||
int flags);
|
||||
extern ssize_t _user_recvfrom(int socket, void *data, size_t length,
|
||||
int flags, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
extern ssize_t _user_recvmsg(int socket, struct msghdr *message,
|
||||
int flags);
|
||||
extern ssize_t _user_send(int socket, const void *data, size_t length,
|
||||
int flags);
|
||||
extern ssize_t _user_sendto(int socket, const void *data, size_t length,
|
||||
int flags, const struct sockaddr *address,
|
||||
socklen_t addressLength);
|
||||
extern ssize_t _user_sendmsg(int socket, const struct msghdr *message,
|
||||
int flags);
|
||||
extern status_t _user_getsockopt(int socket, int level, int option,
|
||||
void *value, socklen_t *_length);
|
||||
extern status_t _user_setsockopt(int socket, int level, int option,
|
||||
const void *value, socklen_t length);
|
||||
extern status_t _user_getpeername(int socket, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
extern status_t _user_getsockname(int socket, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
extern int _user_sockatmark(int socket);
|
||||
extern status_t _user_socketpair(int family, int type, int protocol,
|
||||
int *socketVector);
|
||||
extern status_t _user_get_next_socket_stat(int family, uint32 *cookie,
|
||||
struct net_stat *stat);
|
||||
int _user_socket(int family, int type, int protocol);
|
||||
status_t _user_bind(int socket, const struct sockaddr *address,
|
||||
socklen_t addressLength);
|
||||
status_t _user_shutdown_socket(int socket, int how);
|
||||
status_t _user_connect(int socket, const struct sockaddr *address,
|
||||
socklen_t addressLength);
|
||||
status_t _user_listen(int socket, int backlog);
|
||||
int _user_accept(int socket, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
ssize_t _user_recv(int socket, void *data, size_t length, int flags);
|
||||
ssize_t _user_recvfrom(int socket, void *data, size_t length, int flags,
|
||||
struct sockaddr *address, socklen_t *_addressLength);
|
||||
ssize_t _user_recvmsg(int socket, struct msghdr *message, int flags);
|
||||
ssize_t _user_send(int socket, const void *data, size_t length, int flags);
|
||||
ssize_t _user_sendto(int socket, const void *data, size_t length, int flags,
|
||||
const struct sockaddr *address, socklen_t addressLength);
|
||||
ssize_t _user_sendmsg(int socket, const struct msghdr *message, int flags);
|
||||
status_t _user_getsockopt(int socket, int level, int option, void *value,
|
||||
socklen_t *_length);
|
||||
status_t _user_setsockopt(int socket, int level, int option,
|
||||
const void *value, socklen_t length);
|
||||
status_t _user_getpeername(int socket, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
status_t _user_getsockname(int socket, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
int _user_sockatmark(int socket);
|
||||
status_t _user_socketpair(int family, int type, int protocol,
|
||||
int *socketVector);
|
||||
status_t _user_get_next_socket_stat(int family, uint32 *cookie,
|
||||
struct net_stat *stat);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -286,14 +303,13 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
status_t vfs_asynchronous_read_pages(struct vnode* vnode, void* cookie,
|
||||
off_t pos, const iovec* vecs, size_t count, size_t numBytes,
|
||||
uint32 flags, AsyncIOCallback* callback);
|
||||
|
||||
status_t vfs_asynchronous_write_pages(struct vnode* vnode, void* cookie,
|
||||
off_t pos, const iovec* vecs, size_t count, size_t numBytes,
|
||||
uint32 flags, AsyncIOCallback* callback);
|
||||
status_t vfs_asynchronous_read_pages(struct vnode* vnode, void* cookie,
|
||||
off_t pos, const iovec* vecs, size_t count, size_t numBytes,
|
||||
uint32 flags, AsyncIOCallback* callback);
|
||||
|
||||
status_t vfs_asynchronous_write_pages(struct vnode* vnode, void* cookie,
|
||||
off_t pos, const iovec* vecs, size_t count, size_t numBytes,
|
||||
uint32 flags, AsyncIOCallback* callback);
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct attr_info;
|
||||
struct dirent;
|
||||
struct Elf32_Sym;
|
||||
struct fd_info;
|
||||
@@ -250,10 +251,16 @@ extern ssize_t _kern_select(int numfds, struct fd_set *readSet,
|
||||
bigtime_t timeout, const sigset_t *sigMask);
|
||||
extern ssize_t _kern_poll(struct pollfd *fds, int numFDs,
|
||||
bigtime_t timeout);
|
||||
|
||||
extern int _kern_open_attr_dir(int fd, const char *path);
|
||||
extern int _kern_create_attr(int fd, const char *name, uint32 type,
|
||||
int openMode);
|
||||
extern int _kern_open_attr(int fd, const char *name, int openMode);
|
||||
extern ssize_t _kern_read_attr(int fd, const char *attribute, off_t pos,
|
||||
void *buffer, size_t readBytes);
|
||||
extern ssize_t _kern_write_attr(int fd, const char *attribute, uint32 type,
|
||||
off_t pos, const void *buffer, size_t readBytes);
|
||||
extern status_t _kern_stat_attr(int fd, const char *attribute,
|
||||
struct attr_info *attrInfo);
|
||||
extern int _kern_open_attr(int fd, const char* path, const char *name,
|
||||
uint32 type, int openMode);
|
||||
extern status_t _kern_remove_attr(int fd, const char *name);
|
||||
extern status_t _kern_rename_attr(int fromFile, const char *fromName,
|
||||
int toFile, const char *toName);
|
||||
|
||||
@@ -1202,7 +1202,7 @@ AboutView::_AddCopyrightsFromAttribute()
|
||||
}
|
||||
|
||||
// open the attribute
|
||||
int attrFD = fs_open_attr(appFD, "COPYRIGHTS", B_STRING_TYPE, O_RDONLY);
|
||||
int attrFD = fs_fopen_attr(appFD, "COPYRIGHTS", B_STRING_TYPE, O_RDONLY);
|
||||
close(appFD);
|
||||
if (attrFD < 0)
|
||||
return;
|
||||
|
||||
@@ -168,7 +168,7 @@ sv_rewind(struct irs_sv *sv)
|
||||
return;
|
||||
|
||||
// open the attribute
|
||||
int attrFD = fs_open_attr(libraryFD, "services", B_STRING_TYPE, O_RDONLY);
|
||||
int attrFD = fs_fopen_attr(libraryFD, "services", B_STRING_TYPE, O_RDONLY);
|
||||
close(libraryFD);
|
||||
if (attrFD < 0)
|
||||
return;
|
||||
|
||||
+128
-41
@@ -21,6 +21,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <fs_attr.h>
|
||||
#include <fs_info.h>
|
||||
#include <fs_interface.h>
|
||||
#include <fs_volume.h>
|
||||
@@ -1251,7 +1252,8 @@ static status_t
|
||||
get_vnode(dev_t mountID, ino_t vnodeID, struct vnode** _vnode, bool canWait,
|
||||
int reenter)
|
||||
{
|
||||
FUNCTION(("get_vnode: mountid %ld vnid 0x%Lx %p\n", mountID, vnodeID, _vnode));
|
||||
FUNCTION(("get_vnode: mountid %ld vnid 0x%Lx %p\n", mountID, vnodeID,
|
||||
_vnode));
|
||||
|
||||
mutex_lock(&sVnodeMutex);
|
||||
|
||||
@@ -1263,7 +1265,8 @@ restart:
|
||||
mutex_unlock(&sVnodeMutex);
|
||||
if (!canWait || --tries < 0) {
|
||||
// vnode doesn't seem to become unbusy
|
||||
dprintf("vnode %ld:%Ld is not becoming unbusy!\n", mountID, vnodeID);
|
||||
dprintf("vnode %ld:%Ld is not becoming unbusy!\n", mountID,
|
||||
vnodeID);
|
||||
return B_BUSY;
|
||||
}
|
||||
snooze(10000); // 10 ms
|
||||
@@ -5155,7 +5158,8 @@ file_create(int fd, char* path, int openMode, int perms, bool kernel)
|
||||
struct vnode* directory;
|
||||
int status;
|
||||
|
||||
FUNCTION(("file_create: path '%s', omode %x, perms %d, kernel %d\n", path, openMode, perms, kernel));
|
||||
FUNCTION(("file_create: path '%s', omode %x, perms %d, kernel %d\n", path,
|
||||
openMode, perms, kernel));
|
||||
|
||||
// get directory to put the new file in
|
||||
status = fd_and_path_to_dir_vnode(fd, path, &directory, name, kernel);
|
||||
@@ -6247,30 +6251,33 @@ attr_dir_rewind(struct file_descriptor* descriptor)
|
||||
|
||||
|
||||
static int
|
||||
attr_create(int fd, const char* name, uint32 type, int openMode, bool kernel)
|
||||
attr_create(int fd, char* path, const char* name, uint32 type,
|
||||
int openMode, bool kernel)
|
||||
{
|
||||
struct vnode* vnode;
|
||||
void* cookie;
|
||||
int status;
|
||||
|
||||
if (name == NULL || *name == '\0')
|
||||
return B_BAD_VALUE;
|
||||
|
||||
vnode = get_vnode_from_fd(fd, kernel);
|
||||
if (vnode == NULL)
|
||||
return B_FILE_ERROR;
|
||||
struct vnode* vnode;
|
||||
status_t status = fd_and_path_to_vnode(fd, path,
|
||||
(openMode & O_NOTRAVERSE) != 0, &vnode, NULL, kernel);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
if (!HAS_FS_CALL(vnode, create_attr)) {
|
||||
status = EROFS;
|
||||
goto err;
|
||||
}
|
||||
|
||||
void* cookie;
|
||||
status = FS_CALL(vnode, create_attr, name, type, openMode, &cookie);
|
||||
if (status < B_OK)
|
||||
if (status != B_OK)
|
||||
goto err;
|
||||
|
||||
if ((status = get_new_fd(FDTYPE_ATTR, NULL, vnode, cookie, openMode, kernel)) >= 0)
|
||||
return status;
|
||||
fd = get_new_fd(FDTYPE_ATTR, NULL, vnode, cookie, openMode, kernel);
|
||||
if (fd >= 0)
|
||||
return fd;
|
||||
|
||||
status = fd;
|
||||
|
||||
FS_CALL(vnode, close_attr, cookie);
|
||||
FS_CALL(vnode, free_attr_cookie, cookie);
|
||||
@@ -6285,31 +6292,33 @@ err:
|
||||
|
||||
|
||||
static int
|
||||
attr_open(int fd, const char* name, int openMode, bool kernel)
|
||||
attr_open(int fd, char* path, const char* name, int openMode, bool kernel)
|
||||
{
|
||||
struct vnode* vnode;
|
||||
void* cookie;
|
||||
int status;
|
||||
|
||||
if (name == NULL || *name == '\0')
|
||||
return B_BAD_VALUE;
|
||||
|
||||
vnode = get_vnode_from_fd(fd, kernel);
|
||||
if (vnode == NULL)
|
||||
return B_FILE_ERROR;
|
||||
struct vnode* vnode;
|
||||
status_t status = fd_and_path_to_vnode(fd, path,
|
||||
(openMode & O_NOTRAVERSE) != 0, &vnode, NULL, kernel);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
if (!HAS_FS_CALL(vnode, open_attr)) {
|
||||
status = EOPNOTSUPP;
|
||||
goto err;
|
||||
}
|
||||
|
||||
void* cookie;
|
||||
status = FS_CALL(vnode, open_attr, name, openMode, &cookie);
|
||||
if (status < B_OK)
|
||||
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, NULL, vnode, cookie, openMode, kernel)) >= 0)
|
||||
return status;
|
||||
fd = get_new_fd(FDTYPE_ATTR, NULL, vnode, cookie, openMode, kernel);
|
||||
if (fd >= 0)
|
||||
return fd;
|
||||
|
||||
status = fd;
|
||||
|
||||
FS_CALL(vnode, close_attr, cookie);
|
||||
FS_CALL(vnode, free_attr_cookie, cookie);
|
||||
@@ -8105,16 +8114,19 @@ _kern_open_attr_dir(int fd, const char* path)
|
||||
|
||||
|
||||
int
|
||||
_kern_create_attr(int fd, const char* name, uint32 type, int openMode)
|
||||
_kern_open_attr(int fd, const char* path, const char* name, uint32 type,
|
||||
int openMode)
|
||||
{
|
||||
return attr_create(fd, name, type, openMode, true);
|
||||
}
|
||||
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
||||
if (pathBuffer.InitCheck() != B_OK)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
if ((openMode & O_CREAT) != 0) {
|
||||
return attr_create(fd, pathBuffer.LockBuffer(), name, type, openMode,
|
||||
true);
|
||||
}
|
||||
|
||||
int
|
||||
_kern_open_attr(int fd, const char* name, int openMode)
|
||||
{
|
||||
return attr_open(fd, name, openMode, true);
|
||||
return attr_open(fd, pathBuffer.LockBuffer(), name, openMode, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -9069,21 +9081,79 @@ _user_open_attr_dir(int fd, const char* userPath)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_user_create_attr(int fd, const char* userName, uint32 type, int openMode)
|
||||
ssize_t
|
||||
_user_read_attr(int fd, const char* attribute, off_t pos, void* userBuffer,
|
||||
size_t readBytes)
|
||||
{
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
int attr = attr_open(fd, NULL, attribute, O_RDONLY, false);
|
||||
if (attr < 0)
|
||||
return attr;
|
||||
|
||||
if (!IS_USER_ADDRESS(userName)
|
||||
|| user_strlcpy(name, userName, B_FILE_NAME_LENGTH) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
ssize_t bytes = _user_read(attr, pos, userBuffer, readBytes);
|
||||
_user_close(attr);
|
||||
|
||||
return attr_create(fd, name, type, openMode, false);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
_user_write_attr(int fd, const char* attribute, uint32 type, off_t pos,
|
||||
const void* buffer, size_t writeBytes)
|
||||
{
|
||||
// Try to support the BeOS typical truncation as well as the position
|
||||
// argument
|
||||
int attr = attr_create(fd, NULL, attribute, type,
|
||||
O_CREAT | O_WRONLY | (pos != 0 ? 0 : O_TRUNC), false);
|
||||
if (attr < 0)
|
||||
return attr;
|
||||
|
||||
ssize_t bytes = _user_write(attr, pos, buffer, writeBytes);
|
||||
_user_close(attr);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_user_stat_attr(int fd, const char* attribute, struct attr_info* userAttrInfo)
|
||||
{
|
||||
int attr = attr_open(fd, NULL, attribute, O_RDONLY, false);
|
||||
if (attr < 0)
|
||||
return attr;
|
||||
|
||||
struct file_descriptor* descriptor
|
||||
= get_fd(get_current_io_context(false), attr);
|
||||
if (descriptor == NULL) {
|
||||
_user_close(attr);
|
||||
return B_FILE_ERROR;
|
||||
}
|
||||
|
||||
struct stat stat;
|
||||
status_t status;
|
||||
if (descriptor->ops->fd_read_stat)
|
||||
status = descriptor->ops->fd_read_stat(descriptor, &stat);
|
||||
else
|
||||
status = EOPNOTSUPP;
|
||||
|
||||
put_fd(descriptor);
|
||||
_user_close(attr);
|
||||
|
||||
if (status == B_OK) {
|
||||
attr_info info;
|
||||
info.type = stat.st_type;
|
||||
info.size = stat.st_size;
|
||||
|
||||
if (user_memcpy(userAttrInfo, &info, sizeof(struct attr_info)) != B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_user_open_attr(int fd, const char* userName, int openMode)
|
||||
_user_open_attr(int fd, const char* userPath, const char* userName,
|
||||
uint32 type, int openMode)
|
||||
{
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
|
||||
@@ -9091,7 +9161,24 @@ _user_open_attr(int fd, const char* userName, int openMode)
|
||||
|| user_strlcpy(name, userName, B_FILE_NAME_LENGTH) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
return attr_open(fd, name, openMode, false);
|
||||
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||
if (pathBuffer.InitCheck() != B_OK)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
char* path = pathBuffer.LockBuffer();
|
||||
|
||||
if (userPath != NULL) {
|
||||
if (!IS_USER_ADDRESS(userPath)
|
||||
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
if ((openMode & O_CREAT) != 0) {
|
||||
return attr_create(fd, userPath ? path : NULL, name, type, openMode,
|
||||
false);
|
||||
}
|
||||
|
||||
return attr_open(fd, userPath ? path : NULL, name, openMode, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -59,13 +59,7 @@ extern "C" ssize_t
|
||||
fs_read_attr(int fd, const char* attribute, uint32 /*type*/, off_t pos,
|
||||
void* buffer, size_t readBytes)
|
||||
{
|
||||
int attr = _kern_open_attr(fd, attribute, O_RDONLY);
|
||||
if (attr < 0)
|
||||
RETURN_AND_SET_ERRNO(attr);
|
||||
|
||||
ssize_t bytes = _kern_read(attr, pos, buffer, readBytes);
|
||||
_kern_close(attr);
|
||||
|
||||
ssize_t bytes = _kern_read_attr(fd, attribute, pos, buffer, readBytes);
|
||||
RETURN_AND_SET_ERRNO(bytes);
|
||||
}
|
||||
|
||||
@@ -74,14 +68,15 @@ extern "C" ssize_t
|
||||
fs_write_attr(int fd, const char* attribute, uint32 type, off_t pos,
|
||||
const void* buffer, size_t writeBytes)
|
||||
{
|
||||
// TODO: move this documentation into the Haiku book!
|
||||
|
||||
// NOTE: This call is deprecated in Haiku and has a number of problems:
|
||||
// On BeOS, it was documented that the "pos" argument is ignored.
|
||||
// However, a number of programs tried to use this call to write large
|
||||
// attributes in a loop anyways. These programs all relied on the broken
|
||||
// or at least inconsistent behaviour to truncate/clobber an existing
|
||||
// attribute. In other words, writing 5 bytes at position 0 into an
|
||||
// attribute that was already 10 bytes long resulted in an attribute of
|
||||
// only 5 bytes length.
|
||||
// On BeOS, it was documented that the "pos" argument is ignored, however,
|
||||
// that did not actually happen if the attribute was backed up by a real
|
||||
// file.
|
||||
// Also, it will truncate any existing attribute, disregarding the specified
|
||||
// position.
|
||||
|
||||
// The implementation of this function tries to stay compatible with
|
||||
// BeOS in that it clobbers the existing attribute when you write at offset
|
||||
// 0, but it also tries to support programs which continue to write more
|
||||
@@ -91,14 +86,8 @@ fs_write_attr(int fd, const char* attribute, uint32 type, off_t pos,
|
||||
// see from this implementation, it saves 2 syscalls per writing a chunk
|
||||
// of data.
|
||||
|
||||
int attr = _kern_create_attr(fd, attribute, type,
|
||||
O_WRONLY | (pos != 0 ? 0 : O_TRUNC));
|
||||
if (attr < 0)
|
||||
RETURN_AND_SET_ERRNO(attr);
|
||||
|
||||
ssize_t bytes = _kern_write(attr, pos, buffer, writeBytes);
|
||||
_kern_close(attr);
|
||||
|
||||
ssize_t bytes = _kern_write_attr(fd, attribute, type, pos, buffer,
|
||||
writeBytes);
|
||||
RETURN_AND_SET_ERRNO(bytes);
|
||||
}
|
||||
|
||||
@@ -115,44 +104,23 @@ fs_remove_attr(int fd, const char* attribute)
|
||||
extern "C" int
|
||||
fs_stat_attr(int fd, const char* attribute, struct attr_info* attrInfo)
|
||||
{
|
||||
int attr = _kern_open_attr(fd, attribute, O_RDONLY);
|
||||
if (attr < 0)
|
||||
RETURN_AND_SET_ERRNO(attr);
|
||||
|
||||
struct stat stat;
|
||||
status_t status = _kern_read_stat(attr, NULL, false, &stat,
|
||||
sizeof(struct stat));
|
||||
if (status == B_OK) {
|
||||
attrInfo->type = stat.st_type;
|
||||
attrInfo->size = stat.st_size;
|
||||
}
|
||||
_kern_close(attr);
|
||||
|
||||
status_t status = _kern_stat_attr(fd, attribute, attrInfo);
|
||||
RETURN_AND_SET_ERRNO(status);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
int
|
||||
fs_open_attr(const char *path, const char *attribute, uint32 type, int openMode)
|
||||
{
|
||||
// TODO: implement fs_open_attr() - or remove it completely
|
||||
// if it will be implemented, rename the current fs_open_attr() to fs_fopen_attr()
|
||||
return B_ERROR;
|
||||
status_t status = _kern_open_attr(-1, path, attribute, type, openMode);
|
||||
RETURN_AND_SET_ERRNO(status);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
extern "C" int
|
||||
fs_open_attr(int fd, const char* attribute, uint32 type, int openMode)
|
||||
fs_fopen_attr(int fd, const char* attribute, uint32 type, int openMode)
|
||||
{
|
||||
status_t status;
|
||||
|
||||
if ((openMode & O_CREAT) != 0)
|
||||
status = _kern_create_attr(fd, attribute, type, openMode);
|
||||
else
|
||||
status = _kern_open_attr(fd, attribute, openMode);
|
||||
|
||||
status_t status = _kern_open_attr(fd, NULL, attribute, type, openMode);
|
||||
RETURN_AND_SET_ERRNO(status);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user