diff options
author | Nick Kledzik <kledzik@apple.com> | 2012-06-20 00:28:54 +0000 |
---|---|---|
committer | Nick Kledzik <kledzik@apple.com> | 2012-06-20 00:28:54 +0000 |
commit | ca077ec5ea41f4537ae58e141781be622d09c786 (patch) | |
tree | 2dc2a2955b3f6c9b950d0fc907d99a18a3375b5b /lib/Support | |
parent | 44b2c82871fad5407930cdf0b90c578fa4e60a3a (diff) | |
download | external_llvm-ca077ec5ea41f4537ae58e141781be622d09c786.zip external_llvm-ca077ec5ea41f4537ae58e141781be622d09c786.tar.gz external_llvm-ca077ec5ea41f4537ae58e141781be622d09c786.tar.bz2 |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158770 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r-- | lib/Support/Unix/PathV2.inc | 78 | ||||
-rw-r--r-- | lib/Support/Windows/PathV2.inc | 46 |
2 files changed, 117 insertions, 7 deletions
diff --git a/lib/Support/Unix/PathV2.inc b/lib/Support/Unix/PathV2.inc index a5630b9..4e431ca 100644 --- a/lib/Support/Unix/PathV2.inc +++ b/lib/Support/Unix/PathV2.inc @@ -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 @@ error_code status(const Twine &path, file_status &result) { 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 @@ error_code status(const Twine &path, file_status &result) { 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 @@ error_code get_magic(const Twine &path, uint32_t len, 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 diff --git a/lib/Support/Windows/PathV2.inc b/lib/Support/Windows/PathV2.inc index 4868b18..c79d8ab 100644 --- a/lib/Support/Windows/PathV2.inc +++ b/lib/Support/Windows/PathV2.inc @@ -497,6 +497,41 @@ handle_status_error: 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 @@ error_code detail::directory_iterator_increment(detail::DirIterState &it) { 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 |