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