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