<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - "operation not permitted" ferror on recursive_directory_iterator despite skip_permission_denied"
   href="https://bugs.llvm.org/show_bug.cgi?id=49526">49526</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>"operation not permitted" ferror on recursive_directory_iterator despite skip_permission_denied
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>ssh@pobox.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>On POSIX filesystem backend type systems the
std::filesystem::recursive_directory_iterator throws a filesystem_error
exception with "operation not permitted" when the opendir/readdir call returns
EPERM instead of EACCES even if
std::filesystem::directory_options::skip_permission_denied is set.

Given the following code:

#include <iostream>
#include <filesystem>

int main(int argc, char* argv[])
{
    fs::path dir{"."};
    if(argc == 2) {
        dir = fs::u8path(argv[1]);
    }

    int totalDirs = 0;
    int totalFiles = 0;
    try {
        for(const auto& de : fs::recursive_directory_iterator(dir,
fs::directory_options::skip_permission_denied)) {
            if(de.is_regular_file()) {
                ++totalFiles;
            }
            else if(de.is_directory()) {
                ++totalDirs;
            }
        }
    }
    catch(fs::filesystem_error fe) {
        std::cerr << "Error: " << fe.what() << std::endl;
        exit(1);
    }
    std::cout << totalFiles << " files in " << totalDirs << " directories" <<
std::endl;
    return 0;
}

This fails for example on macOS when called on the user home directory with:

Error: filesystem error: in recursive_directory_iterator::operator++():
attempting recursion into "/Users/<user>/Library/Application
Support/MobileSync": Operation not permitted

This is due to System Integrity Protection (since macOS 10.14) on that folder
leading to EPERM.

On Linux, called with / it stops when hitting for example a
"/proc/1/task/1/cwd", resulting in EPERM too.

I don't have examples from other POSIX systems, but I would say handling only
EACCES  for the skip_permission_denied option is not enough.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>