Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can not iterate through directory entries on Android #72

Closed
alexeikh opened this issue Apr 10, 2018 · 6 comments
Closed

Can not iterate through directory entries on Android #72

alexeikh opened this issue Apr 10, 2018 · 6 comments

Comments

@alexeikh
Copy link
Contributor

alexeikh commented Apr 10, 2018

Prerequisites

  • Android device with Android OS below 6.0, for example Samsung Galaxy S6 with Android 5.0.2. The issue should be reproducible on Android Emulator as well.
  • Android NDK with enabled Unified Headers, for example version r16b
  • Compiler: Clang (shouldn't be important)
  • STL: GNU STL (shouldn't be important)
  • Selected (minimum) Android API level: 14 (shouldn't be important)

How to reproduce

Compile the following sample code as Android executable.

#include <boost/filesystem.hpp>
#include <iostream>

int main() {
    namespace fs = boost::filesystem;

    fs::directory_iterator iter("/data/local/tmp");
    for (const fs::path& p: iter)
        std::cout << "Directory entry found: " << p.c_str() << std::endl;

    return 0;
}

Copy the resulting executable to the device and run it:

adb push libs/armeabi-v7a/sample-cmdline-app /data/local/tmp/
adb shell /data/local/tmp/sample-cmdline-app

Expected behavior

All directory entries are listed, for example:

Directory entry found: /data/local/tmp/sample-cmdline-app
Directory entry found: /data/local/tmp/some-another-file.txt

Actual behavior

boost::filesystem::filesystem_error is thrown on the second iteration of the loop:

Directory entry found: /data/local/tmp/sample-cmdline-app
terminate called after throwing an instance of 'boost::filesystem::filesystem_error'
  what():  boost::filesystem::directory_iterator::operator++: Function not implemented: "/data/local/tmp"
@alexeikh
Copy link
Contributor Author

alexeikh commented Apr 10, 2018

The cause of this issue seems to be buggy readdir_r() implementation on Android 5.x and below.

If using an old Android NDK without Unified Headers, the issue does not happen, because _POSIX_THREAD_SAFE_FUNCTIONS is not defined and Boost.Filesystem choses to use readdir() instead of readdir_r().

@alexeikh alexeikh changed the title Can not iterate directory on Android Can not iterate through directory entries on Android Apr 10, 2018
@alexeikh
Copy link
Contributor Author

Applying patch #68 fixes the issue.

Lastique added a commit to Lastique/filesystem that referenced this issue Apr 10, 2018
This is an explicit fix for this bug:

boostorg#72

Android developers recommend using readdir instead of readdir_r as it is
already thread-safe:

http://elliotth.blogspot.com/2012/10/how-not-to-use-readdirr3.html
@alexeikh
Copy link
Contributor Author

alexeikh commented Apr 20, 2018

The same issue is also reported on the Boost's Trac:
https://svn.boost.org/trac10/ticket/13172

There, another patch is proposed for the fix:
https://gist.github.com/webmaster128/5912a70d100e9ef341df67b177c465d6

I think, both #68 and errno resetting should be applied. Regarding the errno resetting, it may make sense to reset errno in 2 places: both before the readdir_r() call and before the readdir() call.

@webmaster128 and @rcdailey, you may find it useful that #68 also fixes this issue.

@alexeikh
Copy link
Contributor Author

Pull request #51 implements exactly errno resetting in 2 places and also fixes this issue.

@rcdailey
Copy link

How will we know which version of Boost this fix becomes available in?

@alexeikh
Copy link
Contributor Author

alexeikh commented Jun 6, 2018

The issue has been fixed by merging #51 in.

@alexeikh alexeikh closed this as completed Jun 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants