2 * Copyright 2017, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 /*! Shim over the host Haiku fs_attr API */
8 #define BUILDING_FS_ATTR_HAIKU
9 // so build fs_attr.h will not shadow the fs*attr functions
12 #ifdef BUILDING_FS_SHELL
15 # define B_BAD_VALUE EINVAL
16 # define B_FILE_ERROR EBADF
17 # define B_ERROR EINVAL
18 # define B_ENTRY_NOT_FOUND ENOENT
19 # define B_NO_MEMORY ENOMEM
21 # include <syscalls.h>
24 # include "fs_descriptors.h"
42 using namespace BPrivate
;
53 // # pragma mark - Public API
58 build_fs_open_attr_dir(const char *path
)
60 return fs_open_attr_dir(path
);
64 extern "C" DIR* fs_lopen_attr_dir(const char *path
);
66 build_fs_fopen_attr_dir(int fd
)
69 status_t error
= localFD
.Init(fd
);
75 if (localFD
.FD() < 0) {
76 return fs_lopen_attr_dir(localFD
.Path());
78 return fs_fopen_attr_dir(localFD
.FD());
84 build_fs_close_attr_dir(DIR *dir
)
86 return fs_close_attr_dir(dir
);
90 extern "C" struct dirent
*
91 build_fs_read_attr_dir(DIR *dir
)
93 return fs_read_attr_dir(dir
);
98 build_fs_rewind_attr_dir(DIR *dir
)
100 return fs_rewind_attr_dir(dir
);
105 build_fs_fopen_attr(int fd
, const char *attribute
, uint32 type
, int openMode
)
113 status_t error
= localFD
.Init(fd
);
119 if (localFD
.FD() < 0) {
120 return fs_open_attr(localFD
.Path(), attribute
, type
,
121 openMode
| O_NOTRAVERSE
);
123 return fs_fopen_attr(localFD
.FD(), attribute
, type
, openMode
);
129 build_fs_close_attr(int fd
)
131 return fs_close_attr(fd
);
136 build_fs_read_attr(int fd
, const char* attribute
, uint32 type
, off_t pos
,
137 void *buffer
, size_t readBytes
)
140 status_t error
= localFD
.Init(fd
);
147 if (localFD
.FD() < 0) {
148 int fd
= open(localFD
.Path(), O_RDONLY
| O_NOTRAVERSE
);
149 bytesRead
= fs_read_attr(fd
, attribute
, type
,
150 pos
, buffer
, readBytes
);
153 bytesRead
= fs_read_attr(localFD
.FD(), attribute
, type
,
154 pos
, buffer
, readBytes
);
157 // Make sure, the error code is B_ENTRY_NOT_FOUND, if the attribute
159 if (errno
== ENOATTR
|| errno
== ENODATA
)
160 errno
= B_ENTRY_NOT_FOUND
;
169 build_fs_write_attr(int fd
, const char* attribute
, uint32 type
, off_t pos
,
170 const void *buffer
, size_t writeBytes
)
173 status_t error
= localFD
.Init(fd
);
180 if (localFD
.FD() < 0) {
181 int fd
= open(localFD
.Path(), O_NOTRAVERSE
| O_WRONLY
);
182 written
= fs_write_attr(fd
, attribute
, type
,
183 pos
, buffer
, writeBytes
);
186 written
= fs_write_attr(localFD
.FD(), attribute
, type
,
187 pos
, buffer
, writeBytes
);
195 build_fs_remove_attr(int fd
, const char* attribute
)
198 status_t error
= localFD
.Init(fd
);
206 if (localFD
.FD() < 0) {
207 int fd
= open(localFD
.Path(), O_NOTRAVERSE
| O_WRONLY
);
208 result
= fs_remove_attr(fd
, attribute
);
211 result
= fs_remove_attr(localFD
.FD(), attribute
);
215 // Make sure, the error code is B_ENTRY_NOT_FOUND, if the attribute
217 if (errno
== ENOATTR
|| errno
== ENODATA
)
218 errno
= B_ENTRY_NOT_FOUND
;
226 build_fs_stat_attr(int fd
, const char *attribute
, struct attr_info
*attrInfo
)
228 if (!attribute
|| !attrInfo
) {
234 status_t error
= localFD
.Init(fd
);
241 if (localFD
.FD() < 0) {
242 int fd
= open(localFD
.Path(), O_NOTRAVERSE
| O_RDONLY
);
243 result
= fs_stat_attr(fd
, attribute
, attrInfo
);
246 result
= fs_stat_attr(localFD
.FD(), attribute
, attrInfo
);
253 // #pragma mark - Private Syscalls
256 #ifndef BUILDING_FS_SHELL
258 // _kern_open_attr_dir
260 _kern_open_attr_dir(int fd
, const char *path
)
262 // get node ref for the node
264 status_t error
= _kern_read_stat(fd
, path
, false, &st
,
265 sizeof(struct stat
));
274 // If a path was given, get a usable path.
276 status_t error
= get_path(fd
, path
, realPath
);
280 dir
= build_fs_open_attr_dir(realPath
.c_str());
282 dir
= build_fs_fopen_attr_dir(fd
);
288 AttrDirDescriptor
*descriptor
= new AttrDirDescriptor(dir
, ref
);
289 return add_descriptor(descriptor
);
294 _kern_rename_attr(int fromFile
, const char *fromName
, int toFile
,
303 _kern_remove_attr(int fd
, const char *name
)
308 if (build_fs_remove_attr(fd
, name
) < 0)
313 #endif // ! BUILDING_FS_SHELL