xref: /haiku/src/system/libroot/os/fs_query.cpp (revision 1e36cfc2721ef13a187c6f7354dc9cbc485e89d3)
1 /*
2  * Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <fs_query.h>
8 
9 #include <stdlib.h>
10 #include <string.h>
11 #include <fcntl.h>
12 #include <errno.h>
13 
14 #include "syscalls.h"
15 
16 
17 // for the DIR structure
18 #define BUFFER_SIZE 2048
19 
20 
21 static DIR *
22 open_query_etc(dev_t device, const char *query,
23 	uint32 flags, port_id port, int32 token)
24 {
25 	if (device < 0 || query == NULL || query[0] == '\0') {
26 		errno = B_BAD_VALUE;
27 		return NULL;
28 	}
29 
30 	// open
31 	int fd = _kern_open_query(device, query, strlen(query), flags, port, token);
32 	if (fd < 0) {
33 		errno = fd;
34 		return NULL;
35 	}
36 
37 	// allocate a DIR
38 	DIR *dir = (DIR *)malloc(BUFFER_SIZE);
39 	if (!dir) {
40 		_kern_close(fd);
41 		errno = B_NO_MEMORY;
42 		return NULL;
43 	}
44 	dir->fd = fd;
45 	return dir;
46 }
47 
48 
49 DIR *
50 fs_open_query(dev_t device, const char *query, uint32 flags)
51 {
52 	return open_query_etc(device, query, flags, -1, -1);
53 }
54 
55 
56 DIR *
57 fs_open_live_query(dev_t device, const char *query,
58 	uint32 flags, port_id port, int32 token)
59 {
60 	// check parameters
61 	if (port < 0) {
62 		errno = B_BAD_VALUE;
63 		return NULL;
64 	}
65 
66 	return open_query_etc(device, query, flags | B_LIVE_QUERY, port, token);
67 }
68 
69 
70 int
71 fs_close_query(DIR *dir)
72 {
73 	if (dir == NULL) {
74 		errno = B_BAD_VALUE;
75 		return -1;
76 	}
77 
78 	int fd = dir->fd;
79 	free(dir);
80 	return _kern_close(fd);
81 }
82 
83 
84 struct dirent *
85 fs_read_query(DIR *dir)
86 {
87 	// check parameters
88 	if (dir == NULL) {
89 		errno = B_BAD_VALUE;
90 		return NULL;
91 	}
92 
93 	// read
94 	int32 bufferSize = BUFFER_SIZE - ((uint8 *)&dir->ent - (uint8 *)dir);
95 	ssize_t result = _kern_read_dir(dir->fd, &dir->ent, bufferSize, 1);
96 	if (result < 0) {
97 		errno = result;
98 		return NULL;
99 	}
100 	if (result == 0) {
101 		errno = B_ENTRY_NOT_FOUND;
102 		return NULL;
103 	}
104 	return &dir->ent;
105 }
106 
107 
108 status_t
109 get_path_for_dirent(struct dirent *dent, char *buffer, size_t length)
110 {
111 	if (dent == NULL || buffer == NULL)
112 		return B_BAD_VALUE;
113 
114 	return _kern_entry_ref_to_path(dent->d_pdev, dent->d_pino, dent->d_name,
115 		buffer, length);
116 }
117 
118