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