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