1
1
/* A handle to a directory
2
- (C) 2017 Niall Douglas <http://www.nedproductions.biz/> (20 commits)
2
+ (C) 2017-2024 Niall Douglas <http://www.nedproductions.biz/> (20 commits)
3
3
File Created: Aug 2017
4
4
5
5
@@ -37,6 +37,11 @@ http://www.boost.org/LICENSE_1_0.txt)
37
37
#include < sys/stat.h>
38
38
#include < sys/syscall.h>
39
39
40
+ #ifdef __APPLE__
41
+ extern " C" int _getdirentries (int , char *, int , long *);
42
+ extern " C" size_t __getdirentries64 (int fd, void *buf, size_t bufsize, __darwin_off_t *basep);
43
+ #endif
44
+
40
45
LLFIO_V2_NAMESPACE_BEGIN
41
46
42
47
result<directory_handle> directory_handle::directory (const path_handle &base, path_view_type path, mode _mode, creation _creation, caching _caching,
@@ -71,7 +76,7 @@ result<directory_handle> directory_handle::directory(const path_handle &base, pa
71
76
#ifdef O_DIRECTORY
72
77
attribs |= O_DIRECTORY;
73
78
#endif
74
- #ifdef O_SEARCH
79
+ #if defined( O_SEARCH) && !defined(__APPLE__) // Newer Mac OS defines this, but setting it breaks enumeration
75
80
attribs |= O_SEARCH;
76
81
#endif
77
82
if (base.is_valid () && path.empty ())
@@ -81,7 +86,8 @@ result<directory_handle> directory_handle::directory(const path_handle &base, pa
81
86
path = " ." ;
82
87
}
83
88
path_view::zero_terminated_rendered_path<> zpath (path);
84
- auto rename_random_dir_over_existing_dir = [_mode, _caching, flags](const path_handle &base, path_view_type path) -> result<directory_handle> {
89
+ auto rename_random_dir_over_existing_dir = [_mode, _caching, flags](const path_handle &base, path_view_type path) -> result<directory_handle>
90
+ {
85
91
// Take a path handle to the directory containing the file
86
92
auto path_parent = path.parent_path ();
87
93
path_handle dirh;
@@ -343,11 +349,19 @@ result<directory_handle::buffers_type> directory_handle::read(io_request<buffers
343
349
using dirent = dirent64;
344
350
#endif
345
351
#ifdef __APPLE__
346
- // OS X defines a getdirentries64() kernel syscall which can emulate getdents
347
352
typedef int (*getdents_emulation_t )(int , char *, unsigned );
348
- static getdents_emulation_t getdents = static_cast <getdents_emulation_t >([](int fd, char *buf, unsigned count) -> int {
349
- off_t foo;
350
- return syscall (SYS_getdirentries64, fd, buf, count, &foo);
353
+ static getdents_emulation_t getdents = static_cast <getdents_emulation_t >(
354
+ [](int fd, char *buf, unsigned count) -> int
355
+ {
356
+ #if __DARWIN_64_BIT_INO_T
357
+ __darwin_off_t foo = 0 ;
358
+ uint64_t *flags = (uint64_t *) (buf + count - sizeof (uint64_t ));
359
+ *flags = 0 ;
360
+ return (int ) __getdirentries64 (fd, buf, count, &foo);
361
+ #else
362
+ long foo = 0 ;
363
+ return _getdirentries (fd, buf, (int ) count, &foo);
364
+ #endif
351
365
});
352
366
#endif
353
367
if (!req.buffers ._kernel_buffer && req.kernelbuffer .empty ())
0 commit comments