1/* 2 * Copyright 2002-2011, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include <fs_attr.h> 8 9#include <syscall_utils.h> 10#include <errno.h> 11#include <fcntl.h> 12#include <stdlib.h> 13 14#include <dirent_private.h> 15#include <errno_private.h> 16#include <syscalls.h> 17#include <syscall_utils.h> 18 19 20// TODO: think about adding special syscalls for the read/write/stat functions 21// to speed them up 22 23 24static DIR * 25open_attr_dir(int file, const char *path, bool traverse) 26{ 27 DIR *dir; 28 29 int fd = _kern_open_attr_dir(file, path, traverse); 30 if (fd < 0) { 31 __set_errno(fd); 32 return NULL; 33 } 34 35 // allocate the DIR structure 36 if ((dir = __create_dir_struct(fd)) == NULL) { 37 _kern_close(fd); 38 return NULL; 39 } 40 41 return dir; 42} 43 44 45// #pragma mark - 46 47 48extern "C" ssize_t 49fs_read_attr(int fd, const char* attribute, uint32 /*type*/, off_t pos, 50 void* buffer, size_t readBytes) 51{ 52 ssize_t bytes = _kern_read_attr(fd, attribute, pos, buffer, readBytes); 53 RETURN_AND_SET_ERRNO(bytes); 54} 55 56 57extern "C" ssize_t 58fs_write_attr(int fd, const char* attribute, uint32 type, off_t pos, 59 const void* buffer, size_t writeBytes) 60{ 61 // TODO: move this documentation into the Haiku book! 62 63 // NOTE: This call is deprecated in Haiku and has a number of problems: 64 // On BeOS, it was documented that the "pos" argument is ignored, however, 65 // that did not actually happen if the attribute was backed up by a real 66 // file. 67 // Also, it will truncate any existing attribute, disregarding the specified 68 // position. 69 70 // The implementation of this function tries to stay compatible with 71 // BeOS in that it clobbers the existing attribute when you write at offset 72 // 0, but it also tries to support programs which continue to write more 73 // chunks. 74 // The new Haiku way is to use fs_open_attr() to get a regular file handle 75 // and use that for writing, then use fs_close_attr() when done. As you 76 // see from this implementation, it saves 2 syscalls per writing a chunk 77 // of data. 78 79 ssize_t bytes = _kern_write_attr(fd, attribute, type, pos, buffer, 80 writeBytes); 81 RETURN_AND_SET_ERRNO(bytes); 82} 83 84 85extern "C" int 86fs_remove_attr(int fd, const char* attribute) 87{ 88 status_t status = _kern_remove_attr(fd, attribute); 89 90 RETURN_AND_SET_ERRNO(status); 91} 92 93 94extern "C" int 95fs_stat_attr(int fd, const char* attribute, struct attr_info* attrInfo) 96{ 97 status_t status = _kern_stat_attr(fd, attribute, attrInfo); 98 RETURN_AND_SET_ERRNO(status); 99} 100 101 102int 103fs_open_attr(const char *path, const char *attribute, uint32 type, int openMode) 104{ 105 status_t status = _kern_open_attr(-1, path, attribute, type, openMode); 106 RETURN_AND_SET_ERRNO(status); 107} 108 109 110extern "C" int 111fs_fopen_attr(int fd, const char* attribute, uint32 type, int openMode) 112{ 113 status_t status = _kern_open_attr(fd, NULL, attribute, type, openMode); 114 RETURN_AND_SET_ERRNO(status); 115} 116 117 118extern "C" int 119fs_close_attr(int fd) 120{ 121 status_t status = _kern_close(fd); 122 123 RETURN_AND_SET_ERRNO(status); 124} 125 126 127extern "C" DIR* 128fs_open_attr_dir(const char* path) 129{ 130 return open_attr_dir(-1, path, true); 131} 132 133 134extern "C" DIR* 135fs_lopen_attr_dir(const char* path) 136{ 137 return open_attr_dir(-1, path, false); 138} 139 140extern "C" DIR* 141fs_fopen_attr_dir(int fd) 142{ 143 return open_attr_dir(fd, NULL, false); 144} 145 146 147extern "C" int 148fs_close_attr_dir(DIR* dir) 149{ 150 return closedir(dir); 151} 152 153 154extern "C" struct dirent* 155fs_read_attr_dir(DIR* dir) 156{ 157 return readdir(dir); 158} 159 160 161extern "C" void 162fs_rewind_attr_dir(DIR* dir) 163{ 164 rewinddir(dir); 165} 166 167