xref: /haiku/src/system/libroot/os/fs_attr.cpp (revision 9760dcae2038d47442f4658c2575844c6cf92c40)
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