boost::filesystem How to handle directories with no permissions

1.5k Views Asked by At

I am running into an error while trying to enumerate a directory using boost::filesystem.

The error appears when I try to enumerate a directory for which I have no permissions on an SMB shared directory - ie, I have RW on the share but a subdirectory on the share is access denied.

Platform etc:

Windows 10. 
C++ 17 code. 
Visual Studio 2019. 
Unicode VS project (thus the use of std::wstring). 
Shared folders from a Samba server running on Linux.

Sample code below, then details of the fail.

int enumerate(const std::wstring dir_to_enumerate) {

   if (directory.size() == 0)
      return -1;

   boost::filesystem::path dir_to_enumerate(dir_to_enumerate);
   boost::system::error_code ec;

   if ( ! boost::filesystem::exists(dir_to_enumerate, ec))
      return -2;

   if (ec.value())
      return -4;

   if ( ! boost::filesystem::is_directory(dir_to_enumerate))
      return -3;

   boost::filesystem::directory_iterator it{ dir_to_enumerate };

   while (it != boost::filesystem::directory_iterator{}) {
      // ... do stuff
   }

   return 0;
}

Consider a folder C:\temp2 with permissions removed for my account. The test

if ( ! boost::filesystem::exists(dir_to_enumerate, ec))
          return -2;

reliably detects C:\temp2 is not accessible.

Consider a folder "temp2" located on a Samba share T:. This folder on the Linux box is /data/temp2. So the directory passed into the function is L"T:\temp2", and that corresponds to location /data/temp2 on the Linux filesystem.

Samba itself shares the location R/W.

If on the Linux server the EXT4 permissions of the directory /data/temp2 are R/W (mode 700, or 750, or 755 you get the idea) for my account then everything works as expected, I can enumerate the contents of T:\temp2

The problem shows up detecting the following case reliably:

If I set the EXT4 permissions on the directory /data/temp2 to denied (mode 000) then the above code behaves unpredictably...

Sometimes, most of the time, the test

if ( ! boost::filesystem::exists(dir_to_enumerate, ec))
          return -2;

detects T:\temp2 is not accessible.

But occasionally exists() returns true, and we fall thru to testing the boost::filesystem::error_code value.

However the error_code never indicates an error.

In this case the line

boost::filesystem::directory_iterator it{ dir_to_enumerate };

always throws. I can't figure out exactly what it is throwing.

I'm pulling my hair out. Can anyone tell me what I am missing, or even just what the directory_iterator initializer is throwing?

(And... if I may be so forward: please do not tell me to just use std::filesystem. On Visual Studio 2019, and AFAIK C++17 itself, std::filesystem is incomplete. Boost::filesystem works better.)

0

There are 0 best solutions below