C++ filesystemには、パーミッションを取得・設定する機能があります。そんなわけで、たとえばこれをその辺のUnix系システムでg++を使ってコンパイル・実行すれば、755という出力が得られるはずです。

#include <iostream>
#include <experimental/filesystem>
 
int main()
{
  using namespace std::experimental::filesystem;
 
  auto perm = status("/bin/sh").permissions();
  std::cout << std::oct << static_cast<int>(perm) << std::endl;
}

さて、これWindowsだとどうなるのだろう?と思うわけです。試してみました。


これをVisual C++ 2015でコンパイル・実行すると、777という出力になりました。

#include <iostream>
#include <experimental/filesystem>
 
int main()
{
  using namespace std::experimental::filesystem;
 
  auto perm = status(R"(C:\Windows\win.ini)").permissions();
  std::cout << std::oct << static_cast<int>(perm) << std::endl;
}

無条件に777となるのでしょうか?というわけで、Visual C++の実装を眺めてみます。探したところ、VC++ 2015やVC++ 2017ではsrc/src/filesys.hにありました。

  // FILE STATUS FUNCTIONS
_FS_DLL _File_type __CLRCALL_PURE_OR_CDECL _Stat(const TCHAR *_Fname, _Perms *_Pmode)
{  // get file status
WIN32_FILE_ATTRIBUTE_DATA _Data;
 
if (TFUN(GetFileAttributesEx)(_Fname, GetFileExInfoStandard, &_Data))
  {  // get file type and return permissions
  if (_Pmode != 0)
    *_Pmode = _Data.dwFileAttributes & FILE_ATTRIBUTE_READONLY
      ? READONLY_PERMS : perms::all;
  return (_Map_mode(_Data.dwFileAttributes));
  }
else

読み取り専用属性が付いていたら555、そうでなければ777という実装でした。

ちなみに、Boost.Fileystemのほうはどうなっているかというと、実行ファイル・バッチファイルの場合のみ実行ビットを立てる実装となっているようです: filesystem/operations.cpp at boost-1.64.0 · boostorg/filesystem(1805行目からのシンボリックリンクの判定も、VC++と異なります)。

Windowsのファイルシステムのアクセス制御はUnix系のパーミッションとは異なる仕組みである以上、なんらか適当な数値をでっち上げるしかありません。そんなわけなので、どうなっているのか調べてみました。

スポンサード リンク

この記事のカテゴリ

  • ⇒ VC++ filesystemのパーミッション取得の実装
  • ⇒ VC++ filesystemのパーミッション取得の実装