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

Comments

Projects
None yet
2 participants
@alexeikh
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

This comment has been minimized.

Contributor

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 from Can not iterate directory on Android to Can not iterate through directory entries on Android Apr 10, 2018

@alexeikh

This comment has been minimized.

Contributor

alexeikh commented Apr 10, 2018

Applying patch #68 fixes the issue.

Lastique added a commit to Lastique/filesystem that referenced this issue Apr 10, 2018

Disable readdir_r on Android.
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

This comment has been minimized.

Contributor

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

This comment has been minimized.

Contributor

alexeikh commented May 18, 2018

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

@rcdailey

This comment has been minimized.

rcdailey commented May 18, 2018

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

@alexeikh

This comment has been minimized.

Contributor

alexeikh commented Jun 6, 2018

The issue has been fixed by merging #51 in.

@alexeikh alexeikh closed this Jun 6, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment