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