diff --git a/headers/os/kernel/fs_attr.h b/headers/os/kernel/fs_attr.h index 10c2d084a4..c3dabb9781 100644 --- a/headers/os/kernel/fs_attr.h +++ b/headers/os/kernel/fs_attr.h @@ -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); diff --git a/headers/private/kernel/vfs.h b/headers/private/kernel/vfs.h index 87fd06d695..0ef087c164 100644 --- a/headers/private/kernel/vfs.h +++ b/headers/private/kernel/vfs.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. * 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 diff --git a/headers/private/system/syscalls.h b/headers/private/system/syscalls.h index d8846faf4a..9662391bd1 100644 --- a/headers/private/system/syscalls.h +++ b/headers/private/system/syscalls.h @@ -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); diff --git a/src/apps/aboutsystem/AboutSystem.cpp b/src/apps/aboutsystem/AboutSystem.cpp index 40c57394fe..94a052590d 100644 --- a/src/apps/aboutsystem/AboutSystem.cpp +++ b/src/apps/aboutsystem/AboutSystem.cpp @@ -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; diff --git a/src/kits/network/dns/irs/lcl_sv.cpp b/src/kits/network/dns/irs/lcl_sv.cpp index 7ca9984fc1..557170609d 100644 --- a/src/kits/network/dns/irs/lcl_sv.cpp +++ b/src/kits/network/dns/irs/lcl_sv.cpp @@ -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; diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 852d302129..5f399090b6 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -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); } diff --git a/src/system/libroot/os/fs_attr.cpp b/src/system/libroot/os/fs_attr.cpp index bf19d3797e..65a071cb6b 100644 --- a/src/system/libroot/os/fs_attr.cpp +++ b/src/system/libroot/os/fs_attr.cpp @@ -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); }