Skip to content

Commit

Permalink
Fix directory enumeration on Mac OS X, which had started returning
Browse files Browse the repository at this point in the history
"Bad file descriptor" in newer Mac OS X versions.
  • Loading branch information
ned14 committed Aug 21, 2024
1 parent 938b845 commit 9cfc2aa
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 13 deletions.
6 changes: 3 additions & 3 deletions include/llfio/revision.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
#define LLFIO_PREVIOUS_COMMIT_REF dfe95ff5e36c495df11f9a4420ddeb866be4d658
#define LLFIO_PREVIOUS_COMMIT_DATE "2024-08-20 07:56:43 +00:00"
#define LLFIO_PREVIOUS_COMMIT_UNIQUE dfe95ff5
#define LLFIO_PREVIOUS_COMMIT_REF 938b8456e9d575c4455ddeca5fbe808c040b8c88
#define LLFIO_PREVIOUS_COMMIT_DATE "2024-08-20 11:29:01 +00:00"
#define LLFIO_PREVIOUS_COMMIT_UNIQUE 938b8456
28 changes: 21 additions & 7 deletions include/llfio/v2.0/detail/impl/posix/directory_handle.ipp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* A handle to a directory
(C) 2017 Niall Douglas <http://www.nedproductions.biz/> (20 commits)
(C) 2017-2024 Niall Douglas <http://www.nedproductions.biz/> (20 commits)
File Created: Aug 2017
Expand Down Expand Up @@ -37,6 +37,11 @@ http://www.boost.org/LICENSE_1_0.txt)
#include <sys/stat.h>
#include <sys/syscall.h>

#ifdef __APPLE__
extern "C" int _getdirentries(int, char *, int, long *);
extern "C" size_t __getdirentries64(int fd, void *buf, size_t bufsize, __darwin_off_t *basep);
#endif

LLFIO_V2_NAMESPACE_BEGIN

result<directory_handle> directory_handle::directory(const path_handle &base, path_view_type path, mode _mode, creation _creation, caching _caching,
Expand Down Expand Up @@ -71,7 +76,7 @@ result<directory_handle> directory_handle::directory(const path_handle &base, pa
#ifdef O_DIRECTORY
attribs |= O_DIRECTORY;
#endif
#ifdef O_SEARCH
#if defined(O_SEARCH) && !defined(__APPLE__) // Newer Mac OS defines this, but setting it breaks enumeration
attribs |= O_SEARCH;
#endif
if(base.is_valid() && path.empty())
Expand All @@ -81,7 +86,8 @@ result<directory_handle> directory_handle::directory(const path_handle &base, pa
path = ".";
}
path_view::zero_terminated_rendered_path<> zpath(path);
auto rename_random_dir_over_existing_dir = [_mode, _caching, flags](const path_handle &base, path_view_type path) -> result<directory_handle> {
auto rename_random_dir_over_existing_dir = [_mode, _caching, flags](const path_handle &base, path_view_type path) -> result<directory_handle>
{
// Take a path handle to the directory containing the file
auto path_parent = path.parent_path();
path_handle dirh;
Expand Down Expand Up @@ -343,11 +349,19 @@ result<directory_handle::buffers_type> directory_handle::read(io_request<buffers
using dirent = dirent64;
#endif
#ifdef __APPLE__
// OS X defines a getdirentries64() kernel syscall which can emulate getdents
typedef int (*getdents_emulation_t)(int, char *, unsigned);
static getdents_emulation_t getdents = static_cast<getdents_emulation_t>([](int fd, char *buf, unsigned count) -> int {
off_t foo;
return syscall(SYS_getdirentries64, fd, buf, count, &foo);
static getdents_emulation_t getdents = static_cast<getdents_emulation_t>(
[](int fd, char *buf, unsigned count) -> int
{
#if __DARWIN_64_BIT_INO_T
__darwin_off_t foo = 0;
uint64_t *flags = (uint64_t *) (buf + count - sizeof(uint64_t));
*flags = 0;
return (int) __getdirentries64(fd, buf, count, &foo);
#else
long foo = 0;
return _getdirentries(fd, buf, (int) count, &foo);
#endif
});
#endif
if(!req.buffers._kernel_buffer && req.kernelbuffer.empty())
Expand Down
6 changes: 3 additions & 3 deletions include/llfio/v2.0/detail/impl/posix/import.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,16 @@ inline result<int> attribs_from_handle_mode_caching_and_flags(native_handle_type
break;
case handle::mode::attr_read:
case handle::mode::read:
attribs = O_RDONLY;
attribs |= O_RDONLY;
nativeh.behaviour |= native_handle_type::disposition::seekable | native_handle_type::disposition::readable;
break;
case handle::mode::attr_write:
case handle::mode::write:
attribs = O_RDWR;
attribs |= O_RDWR;
nativeh.behaviour |= native_handle_type::disposition::seekable | native_handle_type::disposition::readable | native_handle_type::disposition::writable;
break;
case handle::mode::append:
attribs = O_WRONLY | O_APPEND;
attribs |= O_WRONLY | O_APPEND;
nativeh.behaviour |= native_handle_type::disposition::writable | native_handle_type::disposition::append_only;
break;
}
Expand Down

0 comments on commit 9cfc2aa

Please sign in to comment.