emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.91k stars 3.32k forks source link

std::filesystem::permissions() does not give me the correct permission value #12932

Open Praveer1981 opened 4 years ago

Praveer1981 commented 4 years ago

Hi, I see the different behavior of permissions() function in 1.39.7 and 2.0.8

Below is the sample Code:

#include <stdio.h>
#include <iostream>
#include <filesystem>
#include <fstream>

int main() {

  std::error_code ec;

  // Creates a unique filename that does not name a currently existing file
  const auto fileName = std::tmpnam(nullptr);

  std::wofstream ofs{ fileName };
  ofs.close();

  // check whether file exist or not
  if (std::filesystem::exists(fileName))
  {
    std::cout <<__FILE__<<" "<<__FUNCTION__ <<" "<<__LINE__<<"\n" ;
  }

  std::cout <<__FILE__<<" "<<__FUNCTION__ <<" "<<__LINE__<< " " << " std::filesystem::perms::group_read = " <<(int)std::filesystem::perms::group_read <<"\n" ;
  // now set the permission to the file 
  std::filesystem::permissions(fileName,std::filesystem::perms::group_read,ec);
  if (ec) {
     std::cout <<__FILE__<<" "<<__FUNCTION__ <<" "<<__LINE__<< " " << ec << "\n" ;
  }
  // Now get the File Status
  auto s = std::filesystem::status(fileName, ec);
  // Now get the file permission which was set above
  std::filesystem::perms perm = s.permissions();

  std::cout <<__FILE__<<" "<<__FUNCTION__ <<" "<<__LINE__<< " " << "perm = " <<(int)perm <<" std::filesystem::perms::group_read = " <<(int)std::filesystem::perms::group_read <<"\n" ;
  return 0;
}

I get below output in 1.39.7 perm = 32 std::filesystem::perms::group_read = 32 I get below output in 2.0.8 perm = 0 std::filesystem::perms::group_read = 32

The perm value = 0 means no permission set. However, I had set the permission

Here is the command I used to build and run:

em++ -std=c++17 node a.out.js

reference: https://en.cppreference.com/w/cpp/experimental/fs/perms

Is there anything I am doing wrong here.

kripken commented 4 years ago

As a regression, I'd recommend doing a bisection to find the version in which this regressed. That's usually the fastest way to make progress, if there isn't an obvious explanation for the problem (which I don't see myself).

Praveer1981 commented 4 years ago

@kripken Thanks for your response , let me find out the version in which it was regressed

Praveer1981 commented 4 years ago

I verified and found that the regression is from 1.39.9 version of emscripten.

I tried to run the same program using compiler_explorer. I used Clang trunk(which I assume is Clang 12) and got the correct output(which is Perm = 32)

kripken commented 4 years ago

Thanks @Praveer1981

Looks like this from the Changelog is the likely cause:

- Updated of libc++abi and libc++ to llvm 9.0.0 (#10510)

This may be a regression in libc++, or perhaps the old behavior was wrong before. Next step, I would check if the problem happens in a non-emscripten build of that libc++ version, and if it fails too, if it happens on libc++ trunk (it may have been fixed).

Praveer1981 commented 4 years ago

@kripken Currently, I do not see any test for the filesystem's APIs, Does it make sense to add the tests for the APIs which will help to catch the regression in the future ?

sbc100 commented 4 years ago

Hopefully its enough to test the underlying C APIs and syscalls that are used by the C++ API. I don't think we need to be testing the C++ API directly.. but you might need to use it isolate the exact syscall that broke in this case.

As far as I'm aware emscripten doesn't really support file permissions per-say, it just fakes them, so maybe its easier to fix your application to ignore them which would be more correct and efficient when running on emscripten.

Praveer1981 commented 4 years ago

Thanks @Praveer1981

Looks like this from the Changelog is the likely cause:

- Updated of libc++abi and libc++ to llvm 9.0.0 (#10510)

This may be a regression in libc++, or perhaps the old behavior was wrong before. Next step, I would check if the problem happens in a non-emscripten build of that libc++ version, and if it fails too, if it happens on libc++ trunk (it may have been fixed).

@kripken Did you get chance to check if the problem happens in a non-emscripten build of that libc++ version ?

kripken commented 3 years ago

@Praveer1981 I don't think I personally have the time to do that, sorry.

waterlike86 commented 3 years ago

@sbc100 looks like it might be caused by this -> https://github.com/emscripten-core/emscripten/pull/10474/files the function in library_syscall.js,
this is the output of the test in https://github.com/emscripten-core/emscripten/pull/13581 __sys_fchmodat: function(dirfd, path, mode, varargs) {

if SYSCALL_DEBUG

err('warning: untested syscall');

endif

path = SYSCALLS.getStr(path); path = SYSCALLS.calculateAt(dirfd, path); // mode was 16 mode = SYSCALLS.get(); // mode becomes 0 FS.chmod(path, mode); return 0; }

waterlike86 commented 3 years ago

maybe i should create a new issue. getting the permissions actually works on 2.0.14 +, but changing permissions dont.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 30 days. Feel free to re-open at any time if this issue is still relevant.