KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
dirent.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 dirent.h
4 Copyright (C) 2003 Megan Potter
5 Copyright (C) 2024 Falco Girgis
6
7*/
8
9/** \file dirent.h
10 \brief Directory entry functionality.
11 \ingroup vfs_posix
12
13 This partially implements the standard POSIX dirent.h functionality.
14
15 \author Megan Potter
16 \author Falco Girgis
17*/
18
19#ifndef __SYS_DIRENT_H
20#define __SYS_DIRENT_H
21
22#include <kos/cdefs.h>
23
24__BEGIN_DECLS
25
26#include <unistd.h>
27#include <stdint.h>
28#include <kos/fs.h>
29#include <kos/limits.h>
30
31/** \addtogroup vfs_posix
32 @{
33*/
34
35/** \name Directory File Types
36 \brief POSIX file types for dirent::d_type
37
38 \remark
39 These directory entry types are not part of the POSIX specifican per-se,
40 but are used by BSD and glibc.
41
42 \todo Ensure each VFS driver maps its directory types accordingly
43
44 @{
45*/
46#define DT_UNKNOWN 0 /**< \brief Unknown */
47#define DT_FIFO 1 /**< \brief Named Pipe or FIFO */
48#define DT_CHR 2 /**< \brief Character Device */
49#define DT_DIR 4 /**< \brief Directory */
50#define DT_BLK 6 /**< \brief Block Device */
51#define DT_REG 8 /**< \brief Regular File */
52#define DT_LNK 10 /**< \brief Symbolic Link */
53#define DT_SOCK 12 /**< \brief Local-Domain Socket */
54#define DT_WHT 14 /**< \brief Whiteout (ignored) */
55/** @} */
56
57/** \brief POSIX directory entry structure.
58
59 This structure contains information about a single entry in a directory in
60 the VFS.
61 */
62struct dirent {
63 int d_ino; /**< \brief File unique identifier */
64 off_t d_off; /**< \brief File offset */
65 uint16_t d_reclen; /**< \brief Record length */
66 uint8_t d_type; /**< \brief File type */
67 /** \brief File name
68
69 \warning
70 This field is a flexible array member, which means the structure
71 requires manual over-allocation to reserve storage for this string.
72 \note
73 This allows us to optimize our memory usage by only allocating
74 exactly as many bytes as the string is long for this field.
75 */
76 char d_name[];
77};
78
79/** \brief Type representing a directory stream.
80
81 This type represents a directory stream and is used by the directory reading
82 functions to trace their position in the directory.
83
84 \note
85 The end of this structure is providing extra fixed storage for its inner
86 d_ent.d_name[] FAM, hence the unionization of the d_ent structure along
87 with a d_name[NAME_MAX] extension.
88*/
89typedef struct {
90 /** \brief File descriptor for the directory */
92 /** \brief Union of dirent + extended dirent required for C++ */
93 union {
94 /** \brief Current directory entry */
95 struct dirent d_ent;
96 /** \brief Extended dirent structure with name storage */
97 struct {
98 /** \brief Current directory entry (alias) */
99 struct dirent d_ent2;
100 /** \brief Storage for d_ent::d_name[] FAM */
101 char d_name[NAME_MAX + 1];
102 };
103 };
104} DIR;
105
106// Standard UNIX dir functions. Not all of these are fully functional
107// right now due to lack of support in KOS.
108
109/** \brief Open a directory based on the specified name.
110
111 The directory specified is opened if it exists. A directory stream object is
112 returned for accessing the entries of the directory.
113
114 \note As with other functions for opening files on the VFS,
115 relative paths are permitted for the name parameter of
116 this function.
117
118 \param name The name of the directory to open.
119
120 \return A directory stream object to be used with readdir() on
121 success, NULL on failure. Sets errno as appropriate.
122 \see closedir
123 \see readdir
124*/
125DIR *opendir(const char *name);
126
127/** \brief Closes a directory that was previously opened.
128
129 This function is used to close a directory stream that was previously opened
130 with the opendir() function. You must do this to clean up any resources
131 associated with the directory stream.
132
133 \param dir The directory stream to close.
134
135 \return 0 on success. -1 on error, setting errno as appropriate.
136*/
137int closedir(DIR *dir);
138
139/** \brief Read an entry from a directory stream.
140
141 This function reads the next entry from the directory stream provided,
142 returning the directory entry associated with the next object in the
143 directory.
144
145 \warning Do not free the returned dirent!
146
147 \param dir The directory stream to read from.
148
149 \return A pointer to the next directory entry in the directory
150 or NULL if there are no other entries in the directory.
151 If an error is incurred, NULL will be returned and errno
152 set to indicate the error.
153*/
154struct dirent *readdir(DIR *dir);
155
156/** \brief Retrieve the file descriptor of an opened directory stream.
157
158 This function retrieves the file descriptor of a directory stream that was
159 previously opened with opendir().
160
161 \warning Do not close() the returned file descriptor. It will be
162 closed when closedir() is called on the directory
163 stream.
164
165 \param dirp The directory stream to retrieve the descriptor of.
166
167 \return The file descriptor from the directory stream on success
168 or -1 on failure (sets errno as appropriate).
169*/
170int dirfd(DIR *dirp);
171
172/** \brief Rewind a directory stream to the start of the directory.
173
174 This function rewinds the directory stream so that the next call to the
175 readdir() function will return the first entry in the directory.
176
177 \warning Some filesystems do not support this call. Notably, none
178 of the dcload filesystems support it. Error values will
179 be returned in errno (so set errno to 0, then check
180 after calling the function to see if there was a problem
181 anywhere).
182
183 \param dir The directory stream to rewind.
184*/
185void rewinddir(DIR *dir);
186
187/** \brief Scan, filter, and sort files within a directory.
188
189 This function scans through all files within the directory located at the
190 path given by \p dir, calling \p filter on each entry. Entries for which
191 \p filter returns nonzero are stored within \p namelist and are sorted
192 using qsort() with the comparison function, \p compar. The resulting
193 directory entries are accumulated and stored witin \p namelist.
194
195 \note
196 \p filter and \p compar may be NULL, if you do not wish to filter or sort
197 the files.
198
199 \warning
200 The entries within \p namelist are each independently heap-allocated, then
201 the list itself heap allocated, so each entry must be freed within the list
202 followed by the list itself.
203
204 \param dir The path to the directory to scan
205 \param namelist A pointer through which the list of entries will be
206 returned.
207 \param filter The callback used to filter each directory entry
208 (returning 1 for inclusion, 0 for exclusion).
209 \param compar The callback passed to qsort() to sort \p namelist by
210
211 \retval >=0 On success, the number of directory entries within \p
212 namelist is returned
213 \retval -1 On failure, -1 is returned and errno is set
214
215 \sa alphasort
216*/
217int scandir(const char *__RESTRICT dir, struct dirent ***__RESTRICT namelist,
218 int(*filter)(const struct dirent *),
219 int(*compar)(const struct dirent **, const struct dirent **));
220
221
222/** \brief Comparison function for sorting directory entries alphabetically
223
224 Sorts two directory entries, \p a and \p b in alphabetical order.
225
226 \note
227 This function can be used as the comparison callback passed to scandir(),
228 to sort the returned list of entries in alphabetical order.
229
230 \param a The first directory entry to sort
231 \param b The second directory entry to sort
232
233 \retval Returns an integer value greater than, equal to, or less than
234 zero, depending on whether the name of the directory entry
235 pointed to by \p a is lexically greater than, equal to, or
236 less than the directory entry pointed to by \p b.
237
238 \sa scandir()
239*/
240int alphasort(const struct dirent **a, const struct dirent **b);
241
242/** \brief Not implemented */
243void seekdir(DIR *dir, off_t offset);
244
245/** \brief Not implemented */
246off_t telldir(DIR *dir);
247
248/** @} */
249
250__END_DECLS
251
252#endif
Definitions for builtin attributes and compiler directives.
Virtual filesystem support.
#define __RESTRICT
Definition cdefs.h:176
#define NAME_MAX
Max filename length.
Definition limits.h:25
int file_t
File descriptor type.
Definition fs.h:94
DIR * opendir(const char *name)
Open a directory based on the specified name.
void seekdir(DIR *dir, off_t offset)
Not implemented.
int dirfd(DIR *dirp)
Retrieve the file descriptor of an opened directory stream.
int alphasort(const struct dirent **a, const struct dirent **b)
Comparison function for sorting directory entries alphabetically.
void rewinddir(DIR *dir)
Rewind a directory stream to the start of the directory.
struct dirent * readdir(DIR *dir)
Read an entry from a directory stream.
int closedir(DIR *dir)
Closes a directory that was previously opened.
int scandir(const char *__RESTRICT dir, struct dirent ***__RESTRICT namelist, int(*filter)(const struct dirent *), int(*compar)(const struct dirent **, const struct dirent **))
Scan, filter, and sort files within a directory.
off_t telldir(DIR *dir)
Not implemented.
Limits.
Type representing a directory stream.
Definition dirent.h:89
file_t fd
File descriptor for the directory.
Definition dirent.h:91
POSIX directory entry structure.
Definition dirent.h:62
char d_name[]
File name.
Definition dirent.h:76
uint16_t d_reclen
Record length.
Definition dirent.h:65
uint8_t d_type
File type.
Definition dirent.h:66
int d_ino
File unique identifier.
Definition dirent.h:63
off_t d_off
File offset.
Definition dirent.h:64