1 | //===--- A platform independent Dir class ---------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLVM_LIBC_SRC___SUPPORT_FILE_DIR_H |
10 | #define LLVM_LIBC_SRC___SUPPORT_FILE_DIR_H |
11 | |
12 | #include "src/__support/CPP/span.h" |
13 | #include "src/__support/error_or.h" |
14 | #include "src/__support/threads/mutex.h" |
15 | |
16 | #include <dirent.h> |
17 | #include <stdlib.h> |
18 | |
19 | namespace LIBC_NAMESPACE { |
20 | |
21 | // Platform specific function which will open the directory |name| |
22 | // and return its file descriptor. Upon failure, the error value is returned. |
23 | ErrorOr<int> platform_opendir(const char *name); |
24 | |
25 | // Platform specific function which will close the directory with |
26 | // file descriptor |fd|. Returns 0 on success, or the error number on failure. |
27 | int platform_closedir(int fd); |
28 | |
29 | // Platform specific function which will fetch dirents in to buffer. |
30 | // Returns the number of bytes written into buffer or the error number on |
31 | // failure. |
32 | ErrorOr<size_t> platform_fetch_dirents(int fd, cpp::span<uint8_t> buffer); |
33 | |
34 | // This class is designed to allow implementation of the POSIX dirent.h API. |
35 | // By itself, it is platform independent but calls platform specific |
36 | // functions to perform OS operations. |
37 | class Dir { |
38 | static constexpr size_t BUFSIZE = 1024; |
39 | int fd; |
40 | size_t readptr = 0; // The current read pointer. |
41 | size_t fillsize = 0; // The number of valid bytes availabe in the buffer. |
42 | |
43 | // This is a buffer of struct dirent values which will be fetched |
44 | // from the OS. Since the d_name of struct dirent can be of a variable |
45 | // size, we store the data in a byte array. |
46 | uint8_t buffer[BUFSIZE]; |
47 | |
48 | Mutex mutex; |
49 | |
50 | // A directory is to be opened by the static method open and closed |
51 | // by the close method. So, all constructors and destructor are declared |
52 | // as private. Inappropriate constructors are declared as deleted. |
53 | Dir() = delete; |
54 | Dir(const Dir &) = delete; |
55 | |
56 | explicit Dir(int fdesc) |
57 | : fd(fdesc), readptr(0), fillsize(0), mutex(false, false, false) {} |
58 | ~Dir() = default; |
59 | |
60 | Dir &operator=(const Dir &) = delete; |
61 | |
62 | public: |
63 | static ErrorOr<Dir *> open(const char *path); |
64 | |
65 | ErrorOr<struct ::dirent *> read(); |
66 | |
67 | // Returns 0 on success or the error number on failure. If an error number |
68 | // was returned, then the resources associated with the directory are not |
69 | // cleaned up. |
70 | int close(); |
71 | |
72 | int getfd() { return fd; } |
73 | }; |
74 | |
75 | } // namespace LIBC_NAMESPACE |
76 | |
77 | #endif // LLVM_LIBC_SRC___SUPPORT_FILE_DIR_H |
78 | |