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