[llvm-commits] [llvm] r158770 - in /llvm/trunk: include/llvm/Support/FileSystem.h lib/Support/Unix/PathV2.inc lib/Support/Windows/PathV2.inc unittests/Support/Path.cpp
Galina Kistanova
gkistanova at gmail.com
Thu Jun 21 15:51:11 PDT 2012
Please temporarily disable these tests for Windows, unless Michael is about
to commit this fix.
Thanks
Galina
On Thu, Jun 21, 2012 at 3:37 PM, Nick Kledzik <kledzik at apple.com> wrote:
> These new functions are not implemented for Windows. Michael Spencer
> said he would do the Windows implementation.
>
> In cases like this, is it better to check in the test cases known to not
> work on some platforms, so they can get tested on the others. Or check in
> the test cases disabled?
>
> -Nick
>
> On Jun 21, 2012, at 3:33 PM, Galina Kistanova wrote:
> Hi Nick,
>
> The tests
> LLVM-Unit ::
> Support/Release+Asserts/SupportTests.exe/FileSystemTest.FileMapping
> LLVM-Unit ::
> Support/Release+Asserts/SupportTests.exe/FileSystemTest.Permissions
> fail on one of builders:
>
> http://lab.llvm.org:8011/builders/clang-native-mingw32-win7/builds/2206/steps/test-llvm/logs/fail
> Please have a look at them?
>
> Thanks
>
> Galina
>
> On Tue, Jun 19, 2012 at 5:28 PM, Nick Kledzik <kledzik at apple.com> wrote:
>
>> Author: kledzik
>> Date: Tue Jun 19 19:28:54 2012
>> New Revision: 158770
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=158770&view=rev
>> Log:
>> Add permissions(), map_file_pages(), and unmap_file_pages() to
>> llvm::sys::fs and add unit test. Unix is implemented. Windows side needs
>> to be implemented.
>>
>> Modified:
>> llvm/trunk/include/llvm/Support/FileSystem.h
>> llvm/trunk/lib/Support/Unix/PathV2.inc
>> llvm/trunk/lib/Support/Windows/PathV2.inc
>> llvm/trunk/unittests/Support/Path.cpp
>>
>> Modified: llvm/trunk/include/llvm/Support/FileSystem.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/FileSystem.h?rev=158770&r1=158769&r2=158770&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/Support/FileSystem.h (original)
>> +++ llvm/trunk/include/llvm/Support/FileSystem.h Tue Jun 19 19:28:54 2012
>> @@ -94,6 +94,55 @@
>> uint64_t available;
>> };
>>
>> +
>> +enum perms {
>> + no_perms = 0,
>> + owner_read = 0400,
>> + owner_write = 0200,
>> + owner_exe = 0100,
>> + owner_all = owner_read | owner_write | owner_exe,
>> + group_read = 040,
>> + group_write = 020,
>> + group_exe = 010,
>> + group_all = group_read | group_write | group_exe,
>> + others_read = 04,
>> + others_write = 02,
>> + others_exe = 01,
>> + others_all = others_read | others_write | others_exe,
>> + all_all = owner_all | group_all | others_all,
>> + set_uid_on_exe = 04000,
>> + set_gid_on_exe = 02000,
>> + sticky_bit = 01000,
>> + perms_mask = all_all | set_uid_on_exe | set_gid_on_exe |
>> sticky_bit,
>> + perms_not_known = 0xFFFF,
>> + add_perms = 0x1000,
>> + remove_perms = 0x2000,
>> + symlink_perms = 0x4000
>> +};
>> +
>> +// Helper functions so that you can use & and | to manipulate perms bits:
>> +inline perms operator|(perms l , perms r) {
>> + return static_cast<perms>(
>> + static_cast<unsigned short>(l) | static_cast<unsigned
>> short>(r));
>> +}
>> +inline perms operator&(perms l , perms r) {
>> + return static_cast<perms>(
>> + static_cast<unsigned short>(l) & static_cast<unsigned
>> short>(r));
>> +}
>> +inline perms &operator|=(perms &l, perms r) {
>> + l = l | r;
>> + return l;
>> +}
>> +inline perms &operator&=(perms &l, perms r) {
>> + l = l & r;
>> + return l;
>> +}
>> +inline perms operator~(perms x) {
>> + return static_cast<perms>(~static_cast<unsigned short>(x));
>> +}
>> +
>> +
>> +
>> /// file_status - Represents the result of a call to stat and friends.
>> It has
>> /// a platform specific member to store the result.
>> class file_status
>> @@ -113,12 +162,19 @@
>> friend bool equivalent(file_status A, file_status B);
>> friend error_code status(const Twine &path, file_status &result);
>> file_type Type;
>> + perms Perms;
>> public:
>> - explicit file_status(file_type v=file_type::status_error)
>> - : Type(v) {}
>> + explicit file_status(file_type v=file_type::status_error,
>> + perms prms=perms_not_known)
>> + : Type(v), Perms(prms) {}
>>
>> + // getters
>> file_type type() const { return Type; }
>> + perms permissions() const { return Perms; }
>> +
>> + // setters
>> void type(file_type v) { Type = v; }
>> + void permissions(perms p) { Perms = p; }
>> };
>>
>> /// file_magic - An "enum class" enumeration of file types based on
>> magic (the first
>> @@ -395,6 +451,13 @@
>> /// platform specific error_code.
>> error_code status(const Twine &path, file_status &result);
>>
>> +/// @brief Modifies permission bits on a file
>> +///
>> +/// @param path Input path.
>> +/// @results errc::success if permissions have been changed, otherwise a
>> +/// platform specific error_code.
>> +error_code permissions(const Twine &path, perms prms);
>> +
>> /// @brief Is status available?
>> ///
>> /// @param path Input path.
>> @@ -513,6 +576,33 @@
>> error_code GetMainExecutable(const char *argv0, void *MainAddr,
>> SmallVectorImpl<char> &result);
>>
>> +
>> +/// @brief Memory maps the contents of a file
>> +///
>> +/// @param path Path to file to map.
>> +/// @param file_offset Byte offset in file where mapping should begin.
>> +/// @param size_t Byte length of range of the file to map.
>> +/// @param map_writable If true, the file will be mapped in r/w such
>> +/// that changes to the the mapped buffer will be flushed back
>> +/// to the file. If false, the file will be mapped read-only
>> +/// and the buffer will be read-only.
>> +/// @param result Set to the start address of the mapped buffer.
>> +/// @results errc::success if result has been successfully set,
>> otherwise a
>> +/// platform specific error_code.
>> +error_code map_file_pages(const Twine &path, off_t file_offset, size_t
>> size,
>> + bool map_writable, void *&result);
>> +
>> +
>> +/// @brief Memory unmaps the contents of a file
>> +///
>> +/// @param base Pointer to the start of the buffer.
>> +/// @param size Byte length of the range to unmmap.
>> +/// @results errc::success if result has been successfully set,
>> otherwise a
>> +/// platform specific error_code.
>> +error_code unmap_file_pages(void *base, size_t size);
>> +
>> +
>> +
>> /// @}
>> /// @name Iterators
>> /// @{
>>
>> Modified: llvm/trunk/lib/Support/Unix/PathV2.inc
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/PathV2.inc?rev=158770&r1=158769&r2=158770&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Support/Unix/PathV2.inc (original)
>> +++ llvm/trunk/lib/Support/Unix/PathV2.inc Tue Jun 19 19:28:54 2012
>> @@ -24,6 +24,9 @@
>> #if HAVE_FCNTL_H
>> #include <fcntl.h>
>> #endif
>> +#ifdef HAVE_SYS_MMAN_H
>> +#include <sys/mman.h>
>> +#endif
>> #if HAVE_DIRENT_H
>> # include <dirent.h>
>> # define NAMLEN(dirent) strlen((dirent)->d_name)
>> @@ -325,20 +328,22 @@
>> return ec;
>> }
>>
>> + perms prms = static_cast<perms>(status.st_mode & perms_mask);
>> +
>> if (S_ISDIR(status.st_mode))
>> - result = file_status(file_type::directory_file);
>> + result = file_status(file_type::directory_file, prms);
>> else if (S_ISREG(status.st_mode))
>> - result = file_status(file_type::regular_file);
>> + result = file_status(file_type::regular_file, prms);
>> else if (S_ISBLK(status.st_mode))
>> - result = file_status(file_type::block_file);
>> + result = file_status(file_type::block_file, prms);
>> else if (S_ISCHR(status.st_mode))
>> - result = file_status(file_type::character_file);
>> + result = file_status(file_type::character_file, prms);
>> else if (S_ISFIFO(status.st_mode))
>> - result = file_status(file_type::fifo_file);
>> + result = file_status(file_type::fifo_file, prms);
>> else if (S_ISSOCK(status.st_mode))
>> - result = file_status(file_type::socket_file);
>> + result = file_status(file_type::socket_file, prms);
>> else
>> - result = file_status(file_type::type_unknown);
>> + result = file_status(file_type::type_unknown, prms);
>>
>> result.fs_st_dev = status.st_dev;
>> result.fs_st_ino = status.st_ino;
>> @@ -346,6 +351,35 @@
>> return error_code::success();
>> }
>>
>> +// Modifies permissions on a file.
>> +error_code permissions(const Twine &path, perms prms) {
>> + if ((prms & add_perms) && (prms & remove_perms))
>> + llvm_unreachable("add_perms and remove_perms are mutually
>> exclusive");
>> +
>> + // Get current permissions
>> + file_status info;
>> + if (error_code ec = status(path, info)) {
>> + return ec;
>> + }
>> +
>> + // Set updated permissions.
>> + SmallString<128> path_storage;
>> + StringRef p = path.toNullTerminatedStringRef(path_storage);
>> + perms permsToSet;
>> + if (prms & add_perms) {
>> + permsToSet = (info.permissions() | prms) & perms_mask;
>> + } else if (prms & remove_perms) {
>> + permsToSet = (info.permissions() & ~prms) & perms_mask;
>> + } else {
>> + permsToSet = prms & perms_mask;
>> + }
>> + if (::chmod(p.begin(), static_cast<mode_t>(permsToSet))) {
>> + return error_code(errno, system_category());
>> + }
>> +
>> + return error_code::success();
>> +}
>> +
>> // Since this is most often used for temporary files, mode defaults to
>> 0600.
>> error_code unique_file(const Twine &model, int &result_fd,
>> SmallVectorImpl<char> &result_path,
>> @@ -495,6 +529,36 @@
>> return error_code::success();
>> }
>>
>> +error_code map_file_pages(const Twine &path, off_t file_offset, size_t
>> size,
>> + bool map_writable, void
>> *&result) {
>> + SmallString<128> path_storage;
>> + StringRef name = path.toNullTerminatedStringRef(path_storage);
>> + int oflags = map_writable ? O_RDWR : O_RDONLY;
>> + int ofd = ::open(name.begin(), oflags);
>> + if ( ofd == -1 )
>> + return error_code(errno, system_category());
>> + AutoFD fd(ofd);
>> + int flags = map_writable ? MAP_SHARED : MAP_PRIVATE;
>> + int prot = map_writable ? (PROT_READ|PROT_WRITE) : PROT_READ;
>> +#ifdef MAP_FILE
>> + flags |= MAP_FILE;
>> +#endif
>> + result = ::mmap(0, size, prot, flags, fd, file_offset);
>> + if (result == MAP_FAILED) {
>> + return error_code(errno, system_category());
>> + }
>> +
>> + return error_code::success();
>> +}
>> +
>> +error_code unmap_file_pages(void *base, size_t size) {
>> + if ( ::munmap(base, size) == -1 )
>> + return error_code(errno, system_category());
>> +
>> + return error_code::success();
>> +}
>> +
>> +
>> } // end namespace fs
>> } // end namespace sys
>> } // end namespace llvm
>>
>> Modified: llvm/trunk/lib/Support/Windows/PathV2.inc
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/PathV2.inc?rev=158770&r1=158769&r2=158770&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Support/Windows/PathV2.inc (original)
>> +++ llvm/trunk/lib/Support/Windows/PathV2.inc Tue Jun 19 19:28:54 2012
>> @@ -497,6 +497,41 @@
>> return error_code::success();
>> }
>>
>> +
>> +// Modifies permissions on a file.
>> +error_code permissions(const Twine &path, perms prms) {
>> +#if 0 // verify code below before enabling:
>> + // If the permissions bits are not trying to modify
>> + // "write" permissions, there is nothing to do.
>> + if (!(prms & (owner_write|group_write|others_write)))
>> + return error_code::success();
>> +
>> + SmallString<128> path_storage;
>> + SmallVector<wchar_t, 128> path_utf16;
>> +
>> + if (error_code ec = UTF8ToUTF16(path.toStringRef(path_storage),
>> + path_utf16))
>> + return ec;
>> +
>> + DWORD attributes = ::GetFileAttributesW(path_utf16.begin());
>> +
>> + if (prms & add_perms) {
>> + attributes &= ~FILE_ATTRIBUTE_READONLY;
>> + }
>> + else if (prms & remove_perms) {
>> + attributes |= FILE_ATTRIBUTE_READONLY;
>> + }
>> + else {
>> + assert(0 && "neither add_perms or remove_perms is set");
>> + }
>> +
>> + if ( ! ::SetFileAttributesW(path_utf16.begin(), attributes))
>> + return windows_error(::GetLastError());
>> +#endif
>> + return error_code::success();
>> +}
>> +
>> +
>> // FIXME: mode should be used here and default to user r/w only,
>> // it currently comes in as a UNIX mode.
>> error_code unique_file(const Twine &model, int &result_fd,
>> @@ -755,6 +790,17 @@
>> return error_code::success();
>> }
>>
>> +error_code map_file_pages(const Twine &path, off_t file_offset, size_t
>> size,
>> + bool map_writable, void
>> *&result) {
>> + assert(0 && "NOT IMPLEMENTED");
>> +}
>> +
>> +error_code unmap_file_pages(void *base, size_t size) {
>> + assert(0 && "NOT IMPLEMENTED");
>> +}
>> +
>> +
>> +
>> } // end namespace fs
>> } // end namespace sys
>> } // end namespace llvm
>>
>> Modified: llvm/trunk/unittests/Support/Path.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/Path.cpp?rev=158770&r1=158769&r2=158770&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/unittests/Support/Path.cpp (original)
>> +++ llvm/trunk/unittests/Support/Path.cpp Tue Jun 19 19:28:54 2012
>> @@ -312,4 +312,69 @@
>> }
>> }
>>
>> +
>> +TEST_F(FileSystemTest, Permissions) {
>> + // Create a temp file.
>> + int FileDescriptor;
>> + SmallString<64> TempPath;
>> + ASSERT_NO_ERROR(
>> + fs::unique_file("%%-%%-%%-%%.temp", FileDescriptor, TempPath));
>> +
>> + // Mark file as read-only
>> + const fs::perms AllWrite =
>> fs::owner_write|fs::group_write|fs::others_write;
>> + ASSERT_NO_ERROR(fs::permissions(Twine(TempPath),
>> fs::remove_perms|AllWrite));
>> +
>> + // Verify file is read-only
>> + fs::file_status Status;
>> + ASSERT_NO_ERROR(fs::status(Twine(TempPath), Status));
>> + bool AnyWriteBits = (Status.permissions() & AllWrite);
>> + EXPECT_FALSE(AnyWriteBits);
>> +
>> + // Mark file as read-write
>> + ASSERT_NO_ERROR(fs::permissions(Twine(TempPath),
>> fs::add_perms|AllWrite));
>> +
>> + // Verify file is read-write
>> + ASSERT_NO_ERROR(fs::status(Twine(TempPath), Status));
>> + AnyWriteBits = (Status.permissions() & AllWrite);
>> + EXPECT_TRUE(AnyWriteBits);
>> +}
>> +
>> +TEST_F(FileSystemTest, FileMapping) {
>> + // Create a temp file.
>> + int FileDescriptor;
>> + SmallString<64> TempPath;
>> + ASSERT_NO_ERROR(
>> + fs::unique_file("%%-%%-%%-%%.temp", FileDescriptor, TempPath));
>> +
>> + // Grow temp file to be 4096 bytes
>> + ASSERT_NO_ERROR(sys::fs::resize_file(Twine(TempPath), 4096));
>> +
>> + // Map in temp file and add some content
>> + void* MappedMemory;
>> + ASSERT_NO_ERROR(fs::map_file_pages(Twine(TempPath), 0, 4096,
>> + true /*writable*/, MappedMemory));
>> + char* Memory = reinterpret_cast<char*>(MappedMemory);
>> + strcpy(Memory, "hello there");
>> +
>> + // Unmap temp file
>> + ASSERT_NO_ERROR(fs::unmap_file_pages(MappedMemory, 4096));
>> + MappedMemory = NULL;
>> + Memory = NULL;
>> +
>> + // Map it back in read-only
>> + ASSERT_NO_ERROR(fs::map_file_pages(Twine(TempPath), 0, 4096,
>> + false /*read-only*/, MappedMemory));
>> +
>> + // Verify content
>> + Memory = reinterpret_cast<char*>(MappedMemory);
>> + bool SAME = (strcmp(Memory, "hello there") == 0);
>> + EXPECT_TRUE(SAME);
>> +
>> + // Unmap temp file
>> + ASSERT_NO_ERROR(fs::unmap_file_pages(MappedMemory, 4096));
>> + MappedMemory = NULL;
>> + Memory = NULL;
>> +}
>> +
>> +
>> } // anonymous namespace
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20120621/74def3c4/attachment.html>
More information about the llvm-commits
mailing list