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. 72 73 ssize_t bytes = _kern_write_attr(fd, attribute, type, pos, buffer, 74 writeBytes); 75 RETURN_AND_SET_ERRNO(bytes); 76 } 77 78 79 extern "C" int 80 fs_remove_attr(int fd, const char* attribute) 81 { 82 status_t status = _kern_remove_attr(fd, attribute); 83 84 RETURN_AND_SET_ERRNO(status); 85 } 86 87 88 extern "C" int 89 fs_stat_attr(int fd, const char* attribute, struct attr_info* attrInfo) 90 { 91 status_t status = _kern_stat_attr(fd, attribute, attrInfo); 92 RETURN_AND_SET_ERRNO(status); 93 } 94 95 96 int 97 fs_open_attr(const char *path, const char *attribute, uint32 type, int openMode) 98 { 99 status_t status = _kern_open_attr(AT_FDCWD, path, attribute, type, openMode); 100 RETURN_AND_SET_ERRNO(status); 101 } 102 103 104 extern "C" int 105 fs_fopen_attr(int fd, const char* attribute, uint32 type, int openMode) 106 { 107 status_t status = _kern_open_attr(fd, NULL, attribute, type, openMode); 108 RETURN_AND_SET_ERRNO(status); 109 } 110 111 112 extern "C" int 113 fs_close_attr(int fd) 114 { 115 status_t status = _kern_close(fd); 116 117 RETURN_AND_SET_ERRNO(status); 118 } 119 120 121 extern "C" DIR* 122 fs_open_attr_dir(const char* path) 123 { 124 return open_attr_dir(AT_FDCWD, path, true); 125 } 126 127 128 extern "C" DIR* 129 fs_lopen_attr_dir(const char* path) 130 { 131 return open_attr_dir(AT_FDCWD, path, false); 132 } 133 134 extern "C" DIR* 135 fs_fopen_attr_dir(int fd) 136 { 137 return open_attr_dir(fd, NULL, false); 138 } 139 140 141 extern "C" int 142 fs_close_attr_dir(DIR* dir) 143 { 144 return closedir(dir); 145 } 146 147 148 extern "C" struct dirent* 149 fs_read_attr_dir(DIR* dir) 150 { 151 return readdir(dir); 152 } 153 154 155 extern "C" void 156 fs_rewind_attr_dir(DIR* dir) 157 { 158 rewinddir(dir); 159 } 160