1 //===--- Implementation of a platform independent Dir data structure ------===//
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
7 //===----------------------------------------------------------------------===//
11 #include "src/__support/CPP/mutex.h" // lock_guard
12 #include "src/__support/CPP/new.h"
13 #include "src/__support/error_or.h"
14 #include "src/__support/macros/config.h"
15 #include "src/errno/libc_errno.h" // For error macros
17 namespace LIBC_NAMESPACE_DECL
{
19 ErrorOr
<Dir
*> Dir::open(const char *path
) {
20 auto fd
= platform_opendir(path
);
22 return LIBC_NAMESPACE::Error(fd
.error());
24 LIBC_NAMESPACE::AllocChecker ac
;
25 Dir
*dir
= new (ac
) Dir(fd
.value());
27 return LIBC_NAMESPACE::Error(ENOMEM
);
31 ErrorOr
<struct ::dirent
*> Dir::read() {
32 cpp::lock_guard
lock(mutex
);
33 if (readptr
>= fillsize
) {
34 auto readsize
= platform_fetch_dirents(fd
, buffer
);
36 return LIBC_NAMESPACE::Error(readsize
.error());
37 fillsize
= readsize
.value();
43 struct ::dirent
*d
= reinterpret_cast<struct ::dirent
*>(buffer
+ readptr
);
45 // The d_reclen field is available on Linux but not required by POSIX.
46 readptr
+= d
->d_reclen
;
48 // Other platforms have to implement how the read pointer is to be updated.
49 #error "DIR read pointer update is missing."
56 cpp::lock_guard
lock(mutex
);
57 int retval
= platform_closedir(fd
);
65 } // namespace LIBC_NAMESPACE_DECL