diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -1007,7 +1007,7 @@ return Write(Out); } - unsigned Mode = sys::fs::all_read | sys::fs::all_write | sys::fs::all_exe; + unsigned Mode = sys::fs::all_read | sys::fs::all_write; Expected Temp = sys::fs::TempFile::create(OutputFileName + ".temp-stream-%%%%%%", Mode); if (!Temp) diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/mirror-permissions-unix.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/mirror-permissions-unix.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/mirror-permissions-unix.test @@ -0,0 +1,51 @@ +## The Unix version of this test must use umask(1) because +## llvm-dwarfutil respects the umask in setting output permissions. +## Setting the umask to 0 ensures deterministic permissions across +## test environments. +# UNSUPPORTED: system-windows +# REQUIRES: shell + +# RUN: touch %t +# RUN: chmod 0777 %t +# RUN: ls -l %t | cut -f 1 -d ' ' > %t.0777 +# RUN: chmod 0666 %t +# RUN: ls -l %t | cut -f 1 -d ' ' > %t.0666 +# RUN: chmod 0640 %t +# RUN: ls -l %t | cut -f 1 -d ' ' > %t.0640 + +## Set umask to be permissive of all permissions, +## only test mirroring of permissions. +# RUN: umask 0 + +# RUN: yaml2obj %s -o %t + +# RUN: chmod 0777 %t +# RUN: llvm-dwarfutil --no-garbage-collection %t %t1 +# RUN: ls -l %t1 | cut -f 1 -d ' ' > %t1.perms +# RUN: cmp %t1.perms %t.0777 +# RUN: llvm-dwarfutil --garbage-collection --separate-debug-file %t %t2 +# RUN: ls -l %t2 | cut -f 1 -d ' ' > %t2.perms +# RUN: cmp %t2.perms %t.0777 + +# RUN: chmod 0666 %t +# RUN: llvm-dwarfutil --no-garbage-collection %t %t1 +# RUN: ls -l %t1 | cut -f 1 -d ' ' > %t1.perms +# RUN: cmp %t1.perms %t.0666 +# RUN: llvm-dwarfutil --garbage-collection --separate-debug-file %t %t2 +# RUN: ls -l %t2 | cut -f 1 -d ' ' > %t2.perms +# RUN: cmp %t2.perms %t.0666 + +# RUN: chmod 0640 %t +# RUN: llvm-dwarfutil --no-garbage-collection %t %t1 +# RUN: ls -l %t1 | cut -f 1 -d ' ' > %t1.perms +# RUN: cmp %t1.perms %t.0640 +# RUN: llvm-dwarfutil --garbage-collection --separate-debug-file %t %t2 +# RUN: ls -l %t2 | cut -f 1 -d ' ' > %t2.perms +# RUN: cmp %t2.perms %t.0640 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 diff --git a/llvm/unittests/Support/raw_ostream_test.cpp b/llvm/unittests/Support/raw_ostream_test.cpp --- a/llvm/unittests/Support/raw_ostream_test.cpp +++ b/llvm/unittests/Support/raw_ostream_test.cpp @@ -504,6 +504,31 @@ checkFileData(Path, "HelloWorld"); } +#ifndef _WIN32 +TEST(raw_ostreamTest, filePermissions) { + // Set umask to be permissive of all permissions. + unsigned OldMask = ::umask(0); + + llvm::unittest::TempDir RootTestDirectory("writToOutput", /*Unique*/ true); + SmallString<128> Path(RootTestDirectory.path()); + sys::path::append(Path, "test.txt"); + + ASSERT_THAT_ERROR(writeToOutput(Path, + [](raw_ostream &Out) -> Error { + Out << "HelloWorld"; + return Error::success(); + }), + Succeeded()); + + ErrorOr Perms = llvm::sys::fs::getPermissions(Path); + ASSERT_TRUE(Perms) << "should be able to get permissions"; + // Verify the permission bits set by writeToOutput are read and write only. + EXPECT_EQ(Perms.get(), llvm::sys::fs::all_read | llvm::sys::fs::all_write); + + ::umask(OldMask); +} +#endif + TEST(raw_ostreamTest, writeToNonexistingPath) { StringRef FileName = "/_bad/_path"; std::string ErrorMessage = toString(createFileError(