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 24 static DIR * 25 open_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 48 extern "C" ssize_t 49 fs_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 57 extern "C" ssize_t 58 fs_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 85 extern "C" int 86 fs_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 94 extern "C" int 95 fs_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 102 int 103 fs_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 110 extern "C" int 111 fs_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 118 extern "C" int 119 fs_close_attr(int fd) 120 { 121 status_t status = _kern_close(fd); 122 123 RETURN_AND_SET_ERRNO(status); 124 } 125 126 127 extern "C" DIR* 128 fs_open_attr_dir(const char* path) 129 { 130 return open_attr_dir(-1, path, true); 131 } 132 133 134 extern "C" DIR* 135 fs_lopen_attr_dir(const char* path) 136 { 137 return open_attr_dir(-1, path, false); 138 } 139 140 extern "C" DIR* 141 fs_fopen_attr_dir(int fd) 142 { 143 return open_attr_dir(fd, NULL, false); 144 } 145 146 147 extern "C" int 148 fs_close_attr_dir(DIR* dir) 149 { 150 return closedir(dir); 151 } 152 153 154 extern "C" struct dirent* 155 fs_read_attr_dir(DIR* dir) 156 { 157 return readdir(dir); 158 } 159 160 161 extern "C" void 162 fs_rewind_attr_dir(DIR* dir) 163 { 164 rewinddir(dir); 165 } 166 167