llvm.org GIT mirror llvm / 749d8a5
[Support] Move llvm::MemoryBuffer to sys::fs::file_t Summary: On Windows, Posix integer file descriptors are a compatibility layer over native file handles provided by the C runtime. There is a hard limit on the maximum number of file descriptors that a process can open, and the limit is 8192. LLD typically doesn't run into this limit because it opens input files, maps them into memory, and then immediately closes the file descriptor. This prevents it from running out of FDs. For various reasons, I'd like to open handles to every input file and keep them open during linking. That requires migrating MemoryBuffer over to taking open native file handles instead of integer FDs. Reviewers: aganea, Bigcheese Reviewed By: aganea Subscribers: smeenai, silvas, mehdi_amini, hiraditya, steven_wu, dexonsmith, dang, llvm-commits, zturner Tags: #llvm Differential Revision: https://reviews.llvm.org/D63453 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365588 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner a month ago
18 changed file(s) with 276 addition(s) and 122 deletion(s). Raw diff Collapse all Expand all
647647 /// A version for when a file descriptor is already available.
648648 std::error_code status(int FD, file_status &Result);
649649
650 #ifdef _WIN32
651 /// A version for when a file descriptor is already available.
652 std::error_code status(file_t FD, file_status &Result);
653 #endif
654
650655 /// Get file creation mode mask of the process.
651656 ///
652657 /// @returns Mask reported by umask(2)
962967 FileAccess Access, OpenFlags Flags,
963968 unsigned Mode = 0666);
964969
970 /// Converts from a Posix file descriptor number to a native file handle.
971 /// On Windows, this retreives the underlying handle. On non-Windows, this is a
972 /// no-op.
973 file_t convertFDToNativeFile(int FD);
974
975 #ifndef _WIN32
976 inline file_t convertFDToNativeFile(int FD) { return FD; }
977 #endif
978
979 /// Return an open handle to standard in. On Unix, this is typically FD 0.
980 /// Returns kInvalidFile when the stream is closed.
981 file_t getStdinHandle();
982
983 /// Return an open handle to standard out. On Unix, this is typically FD 1.
984 /// Returns kInvalidFile when the stream is closed.
985 file_t getStdoutHandle();
986
987 /// Return an open handle to standard error. On Unix, this is typically FD 2.
988 /// Returns kInvalidFile when the stream is closed.
989 file_t getStderrHandle();
990
991 /// Reads \p Buf.size() bytes from \p FileHandle into \p Buf. The number of
992 /// bytes actually read is returned in \p BytesRead. On Unix, this is equivalent
993 /// to `*BytesRead = ::read(FD, Buf.data(), Buf.size())`, with error reporting.
994 /// BytesRead will contain zero when reaching EOF.
995 ///
996 /// @param FileHandle File to read from.
997 /// @param Buf Buffer to read into.
998 /// @param BytesRead Output parameter of the number of bytes read.
999 /// @returns The error, if any, or errc::success.
1000 std::error_code readNativeFile(file_t FileHandle, MutableArrayRef Buf,
1001 size_t *BytesRead);
1002
1003 /// Reads \p Buf.size() bytes from \p FileHandle at offset \p Offset into \p
1004 /// Buf. If 'pread' is available, this will use that, otherwise it will use
1005 /// 'lseek'. Bytes requested beyond the end of the file will be zero
1006 /// initialized.
1007 ///
1008 /// @param FileHandle File to read from.
1009 /// @param Buf Buffer to read into.
1010 /// @param Offset Offset into the file at which the read should occur.
1011 /// @returns The error, if any, or errc::success.
1012 std::error_code readNativeFileSlice(file_t FileHandle,
1013 MutableArrayRef Buf, size_t Offset);
1014
9651015 /// @brief Opens the file with the given name in a write-only or read-write
9661016 /// mode, returning its open file descriptor. If the file does not exist, it
9671017 /// is created.
10811131 SmallVectorImpl *RealPath = nullptr);
10821132
10831133 /// @brief Close the file object. This should be used instead of ::close for
1084 /// portability.
1134 /// portability. On error, the caller should assume the file is closed, as is
1135 /// the case for Process::SafelyCloseFileDescriptor
10851136 ///
10861137 /// @param F On input, this is the file to close. On output, the file is
10871138 /// set to kInvalidFile.
1088 void closeFile(file_t &F);
1139 ///
1140 /// @returns An error code if closing the file failed. Typically, an error here
1141 /// means that the filesystem may have failed to perform some buffered writes.
1142 std::error_code closeFile(file_t &F);
10891143
10901144 std::error_code getUniqueID(const Twine Path, UniqueID &Result);
10911145
11151169 size_t Size;
11161170 void *Mapping;
11171171 #ifdef _WIN32
1118 void *FileHandle;
1172 sys::fs::file_t FileHandle;
11191173 #endif
11201174 mapmode Mode;
11211175
1122 std::error_code init(int FD, uint64_t Offset, mapmode Mode);
1176 std::error_code init(sys::fs::file_t FD, uint64_t Offset, mapmode Mode);
11231177
11241178 public:
11251179 mapped_file_region() = delete;
11261180 mapped_file_region(mapped_file_region&) = delete;
11271181 mapped_file_region &operator =(mapped_file_region&) = delete;
11281182
1129 /// \param fd An open file descriptor to map. mapped_file_region takes
1130 /// ownership if closefd is true. It must have been opended in the correct
1131 /// mode.
1132 mapped_file_region(int fd, mapmode mode, size_t length, uint64_t offset,
1183 /// \param fd An open file descriptor to map. Does not take ownership of fd.
1184 mapped_file_region(sys::fs::file_t fd, mapmode mode, size_t length, uint64_t offset,
11331185 std::error_code &ec);
11341186
11351187 ~mapped_file_region();
8989 /// MemoryBuffer. The slice is specified by an \p Offset and \p MapSize.
9090 /// Since this is in the middle of a file, the buffer is not null terminated.
9191 static ErrorOr>
92 getOpenFileSlice(int FD, const Twine &Filename, uint64_t MapSize,
92 getOpenFileSlice(sys::fs::file_t FD, const Twine &Filename, uint64_t MapSize,
9393 int64_t Offset, bool IsVolatile = false);
9494
9595 /// Given an already-open file descriptor, read the file and return a
9999 /// can change outside the user's control, e.g. when libclang tries to parse
100100 /// while the user is editing/updating the file or if the file is on an NFS.
101101 static ErrorOr>
102 getOpenFile(int FD, const Twine &Filename, uint64_t FileSize,
102 getOpenFile(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize,
103103 bool RequiresNullTerminator = true, bool IsVolatile = false);
104104
105105 /// Open the specified memory range as a MemoryBuffer. Note that InputData
4343 Twine(EntryPath), FD, sys::fs::OF_UpdateAtime, &ResultPath);
4444 if (!EC) {
4545 ErrorOr> MBOrErr =
46 MemoryBuffer::getOpenFile(FD, EntryPath,
46 MemoryBuffer::getOpenFile(sys::fs::convertFDToNativeFile(FD),
47 EntryPath,
4748 /*FileSize*/ -1,
4849 /*RequiresNullTerminator*/ false);
4950 close(FD);
8586
8687 // Open the file first to avoid racing with a cache pruner.
8788 ErrorOr> MBOrErr =
88 MemoryBuffer::getOpenFile(TempFile.FD, TempFile.TmpName,
89 /*FileSize*/ -1,
90 /*RequiresNullTerminator*/ false);
89 MemoryBuffer::getOpenFile(
90 sys::fs::convertFDToNativeFile(TempFile.FD), TempFile.TmpName,
91 /*FileSize=*/-1, /*RequiresNullTerminator=*/false);
9192 if (!MBOrErr)
9293 report_fatal_error(Twine("Failed to open new cache file ") +
9394 TempFile.TmpName + ": " +
129129 size_t map_size, off_t offset,
130130 const TargetOptions &options) {
131131 ErrorOr> BufferOrErr =
132 MemoryBuffer::getOpenFileSlice(fd, path, map_size, offset);
132 MemoryBuffer::getOpenFileSlice(sys::fs::convertFDToNativeFile(fd), path,
133 map_size, offset);
133134 if (std::error_code EC = BufferOrErr.getError()) {
134135 Context.emitError(EC.message());
135136 return EC;
354354 Twine(EntryPath), FD, sys::fs::OF_UpdateAtime, &ResultPath);
355355 if (EC)
356356 return EC;
357 ErrorOr> MBOrErr =
358 MemoryBuffer::getOpenFile(FD, EntryPath,
359 /*FileSize*/ -1,
360 /*RequiresNullTerminator*/ false);
357 ErrorOr> MBOrErr = MemoryBuffer::getOpenFile(
358 sys::fs::convertFDToNativeFile(FD), EntryPath,
359 /*FileSize=*/-1, /*RequiresNullTerminator=*/false);
361360 close(FD);
362361 return MBOrErr;
363362 }
7373 Expected NewArchiveMember::getFile(StringRef FileName,
7474 bool Deterministic) {
7575 sys::fs::file_status Status;
76 int FD;
77 if (auto EC = sys::fs::openFileForRead(FileName, FD))
78 return errorCodeToError(EC);
79 assert(FD != -1);
76 auto FDOrErr = sys::fs::openNativeFileForRead(FileName);
77 if (!FDOrErr)
78 return FDOrErr.takeError();
79 sys::fs::file_t FD = *FDOrErr;
80 assert(FD != sys::fs::kInvalidFile);
8081
8182 if (auto EC = sys::fs::status(FD, Status))
8283 return errorCodeToError(EC);
9293 if (!MemberBufferOrErr)
9394 return errorCodeToError(MemberBufferOrErr.getError());
9495
95 if (close(FD) != 0)
96 return errorCodeToError(std::error_code(errno, std::generic_category()));
96 if (auto EC = sys::fs::closeFile(FD))
97 return errorCodeToError(EC);
9798
9899 NewArchiveMember M;
99100 M.Buf = std::move(*MemberBufferOrErr);
146146 // Mmap it.
147147 std::error_code EC;
148148 auto MappedFile = llvm::make_unique(
149 File.FD, fs::mapped_file_region::readwrite, Size, 0, EC);
149 fs::convertFDToNativeFile(File.FD), fs::mapped_file_region::readwrite,
150 Size, 0, EC);
150151
151152 // mmap(2) can fail if the underlying filesystem does not support it.
152153 // If that happens, we fall back to in-memory buffer as the last resort.
181181 }
182182
183183 public:
184 MemoryBufferMMapFile(bool RequiresNullTerminator, int FD, uint64_t Len,
184 MemoryBufferMMapFile(bool RequiresNullTerminator, sys::fs::file_t FD, uint64_t Len,
185185 uint64_t Offset, std::error_code &EC)
186186 : MFR(FD, MB::Mapmode, getLegalMapSize(Len, Offset),
187187 getLegalMapOffset(Offset), EC) {
207207 }
208208
209209 static ErrorOr>
210 getMemoryBufferForStream(int FD, const Twine &BufferName) {
210 getMemoryBufferForStream(sys::fs::file_t FD, const Twine &BufferName) {
211211 const ssize_t ChunkSize = 4096*4;
212212 SmallString Buffer;
213 ssize_t ReadBytes;
213 size_t ReadBytes;
214214 // Read into Buffer until we hit EOF.
215215 do {
216216 Buffer.reserve(Buffer.size() + ChunkSize);
217 ReadBytes = sys::RetryAfterSignal(-1, ::read, FD, Buffer.end(), ChunkSize);
218 if (ReadBytes == -1)
219 return std::error_code(errno, std::generic_category());
217 if (auto EC = sys::fs::readNativeFile(
218 FD, makeMutableArrayRef(Buffer.end(), ChunkSize), &ReadBytes))
219 return EC;
220220 Buffer.set_size(Buffer.size() + ReadBytes);
221221 } while (ReadBytes != 0);
222222
233233
234234 template
235235 static ErrorOr>
236 getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize,
236 getOpenFileImpl(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize,
237237 uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator,
238238 bool IsVolatile);
239239
241241 static ErrorOr>
242242 getFileAux(const Twine &Filename, int64_t FileSize, uint64_t MapSize,
243243 uint64_t Offset, bool RequiresNullTerminator, bool IsVolatile) {
244 int FD;
245 std::error_code EC = sys::fs::openFileForRead(Filename, FD, sys::fs::OF_None);
246
247 if (EC)
248 return EC;
249
244 Expected FDOrErr =
245 sys::fs::openNativeFileForRead(Filename, sys::fs::OF_None);
246 if (!FDOrErr)
247 return errorToErrorCode(FDOrErr.takeError());
248 sys::fs::file_t FD = *FDOrErr;
250249 auto Ret = getOpenFileImpl(FD, Filename, FileSize, MapSize, Offset,
251250 RequiresNullTerminator, IsVolatile);
252 close(FD);
251 sys::fs::closeFile(FD);
253252 return Ret;
254253 }
255254
303302 return SB;
304303 }
305304
306 static bool shouldUseMmap(int FD,
305 static bool shouldUseMmap(sys::fs::file_t FD,
307306 size_t FileSize,
308307 size_t MapSize,
309308 off_t Offset,
361360 static ErrorOr>
362361 getReadWriteFile(const Twine &Filename, uint64_t FileSize, uint64_t MapSize,
363362 uint64_t Offset) {
364 int FD;
365 std::error_code EC = sys::fs::openFileForReadWrite(
366 Filename, FD, sys::fs::CD_OpenExisting, sys::fs::OF_None);
367
368 if (EC)
369 return EC;
363 Expected FDOrErr = sys::fs::openNativeFileForReadWrite(
364 Filename, sys::fs::CD_OpenExisting, sys::fs::OF_None);
365 if (!FDOrErr)
366 return errorToErrorCode(FDOrErr.takeError());
367 sys::fs::file_t FD = *FDOrErr;
370368
371369 // Default is to map the full file.
372370 if (MapSize == uint64_t(-1)) {
390388 MapSize = FileSize;
391389 }
392390
391 std::error_code EC;
393392 std::unique_ptr Result(
394393 new (NamedBufferAlloc(Filename))
395394 MemoryBufferMMapFile(false, FD, MapSize,
413412
414413 template
415414 static ErrorOr>
416 getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize,
415 getOpenFileImpl(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize,
417416 uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator,
418417 bool IsVolatile) {
419418 static int PageSize = sys::Process::getPageSizeEstimate();
458457 return make_error_code(errc::not_enough_memory);
459458 }
460459
461 char *BufPtr = Buf.get()->getBufferStart();
462
463 size_t BytesLeft = MapSize;
464 #ifndef HAVE_PREAD
465 if (lseek(FD, Offset, SEEK_SET) == -1)
466 return std::error_code(errno, std::generic_category());
467 #endif
468
469 while (BytesLeft) {
470 #ifdef HAVE_PREAD
471 ssize_t NumRead = sys::RetryAfterSignal(-1, ::pread, FD, BufPtr, BytesLeft,
472 MapSize - BytesLeft + Offset);
473 #else
474 ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD, BufPtr, BytesLeft);
475 #endif
476 if (NumRead == -1) {
477 // Error while reading.
478 return std::error_code(errno, std::generic_category());
479 }
480 if (NumRead == 0) {
481 memset(BufPtr, 0, BytesLeft); // zero-initialize rest of the buffer.
482 break;
483 }
484 BytesLeft -= NumRead;
485 BufPtr += NumRead;
486 }
460 sys::fs::readNativeFileSlice(FD, Buf->getBuffer(), Offset);
487461
488462 return std::move(Buf);
489463 }
490464
491465 ErrorOr>
492 MemoryBuffer::getOpenFile(int FD, const Twine &Filename, uint64_t FileSize,
466 MemoryBuffer::getOpenFile(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize,
493467 bool RequiresNullTerminator, bool IsVolatile) {
494468 return getOpenFileImpl(FD, Filename, FileSize, FileSize, 0,
495469 RequiresNullTerminator, IsVolatile);
496470 }
497471
498472 ErrorOr>
499 MemoryBuffer::getOpenFileSlice(int FD, const Twine &Filename, uint64_t MapSize,
473 MemoryBuffer::getOpenFileSlice(sys::fs::file_t FD, const Twine &Filename, uint64_t MapSize,
500474 int64_t Offset, bool IsVolatile) {
501475 assert(MapSize != uint64_t(-1));
502476 return getOpenFileImpl(FD, Filename, -1, MapSize, Offset, false,
510484 // fallback if it fails.
511485 sys::ChangeStdinToBinary();
512486
513 return getMemoryBufferForStream(0, "");
487 return getMemoryBufferForStream(sys::fs::getStdinHandle(), "");
514488 }
515489
516490 ErrorOr>
517491 MemoryBuffer::getFileAsStream(const Twine &Filename) {
518 int FD;
519 std::error_code EC = sys::fs::openFileForRead(Filename, FD, sys::fs::OF_None);
520 if (EC)
521 return EC;
492 Expected FDOrErr =
493 sys::fs::openNativeFileForRead(Filename, sys::fs::OF_None);
494 if (!FDOrErr)
495 return errorToErrorCode(FDOrErr.takeError());
496 sys::fs::file_t FD = *FDOrErr;
522497 ErrorOr> Ret =
523498 getMemoryBufferForStream(FD, Filename);
524 close(FD);
499 sys::fs::closeFile(FD);
525500 return Ret;
526501 }
527502
989989 return ResultFD;
990990 }
991991
992 void closeFile(file_t &F) {
993 ::close(F);
992 file_t getStdinHandle() { return 0; }
993 file_t getStdoutHandle() { return 1; }
994 file_t getStderrHandle() { return 2; }
995
996 std::error_code readNativeFile(file_t FD, MutableArrayRef Buf,
997 size_t *BytesRead) {
998 *BytesRead = sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Buf.size());
999 if (ssize_t(*BytesRead) == -1)
1000 return std::error_code(errno, std::generic_category());
1001 return std::error_code();
1002 }
1003
1004 std::error_code readNativeFileSlice(file_t FD, MutableArrayRef Buf,
1005 size_t Offset) {
1006 char *BufPtr = Buf.data();
1007 size_t BytesLeft = Buf.size();
1008
1009 #ifndef HAVE_PREAD
1010 // If we don't have pread, seek to Offset.
1011 if (lseek(FD, Offset, SEEK_SET) == -1)
1012 return std::error_code(errno, std::generic_category());
1013 #endif
1014
1015 while (BytesLeft) {
1016 #ifdef HAVE_PREAD
1017 ssize_t NumRead = sys::RetryAfterSignal(-1, ::pread, FD, BufPtr, BytesLeft,
1018 Buf.size() - BytesLeft + Offset);
1019 #else
1020 ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD, BufPtr, BytesLeft);
1021 #endif
1022 if (NumRead == -1) {
1023 // Error while reading.
1024 return std::error_code(errno, std::generic_category());
1025 }
1026 if (NumRead == 0) {
1027 memset(BufPtr, 0, BytesLeft); // zero-initialize rest of the buffer.
1028 break;
1029 }
1030 BytesLeft -= NumRead;
1031 BufPtr += NumRead;
1032 }
1033 return std::error_code();
1034 }
1035
1036 std::error_code closeFile(file_t &F) {
1037 file_t TmpF = F;
9941038 F = kInvalidFile;
1039 return Process::SafelyCloseFileDescriptor(TmpF);
9951040 }
9961041
9971042 template
5555 using namespace llvm;
5656 using namespace llvm::vfs;
5757
58 using llvm::sys::fs::file_t;
5859 using llvm::sys::fs::file_status;
5960 using llvm::sys::fs::file_type;
61 using llvm::sys::fs::kInvalidFile;
6062 using llvm::sys::fs::perms;
6163 using llvm::sys::fs::UniqueID;
6264
169171 class RealFile : public File {
170172 friend class RealFileSystem;
171173
172 int FD;
174 file_t FD;
173175 Status S;
174176 std::string RealName;
175177
176 RealFile(int FD, StringRef NewName, StringRef NewRealPathName)
178 RealFile(file_t FD, StringRef NewName, StringRef NewRealPathName)
177179 : FD(FD), S(NewName, {}, {}, {}, {}, {},
178180 llvm::sys::fs::file_type::status_error, {}),
179181 RealName(NewRealPathName.str()) {
180 assert(FD >= 0 && "Invalid or inactive file descriptor");
182 assert(FD != kInvalidFile && "Invalid or inactive file descriptor");
181183 }
182184
183185 public:
197199 RealFile::~RealFile() { close(); }
198200
199201 ErrorOr RealFile::status() {
200 assert(FD != -1 && "cannot stat closed file");
202 assert(FD != kInvalidFile && "cannot stat closed file");
201203 if (!S.isStatusKnown()) {
202204 file_status RealStatus;
203205 if (std::error_code EC = sys::fs::status(FD, RealStatus))
214216 ErrorOr>
215217 RealFile::getBuffer(const Twine &Name, int64_t FileSize,
216218 bool RequiresNullTerminator, bool IsVolatile) {
217 assert(FD != -1 && "cannot get buffer for closed file");
219 assert(FD != kInvalidFile && "cannot get buffer for closed file");
218220 return MemoryBuffer::getOpenFile(FD, Name, FileSize, RequiresNullTerminator,
219221 IsVolatile);
220222 }
221223
222224 std::error_code RealFile::close() {
223 std::error_code EC = sys::Process::SafelyCloseFileDescriptor(FD);
224 FD = -1;
225 std::error_code EC = sys::fs::closeFile(FD);
226 FD = kInvalidFile;
225227 return EC;
226228 }
227229
292294
293295 ErrorOr>
294296 RealFileSystem::openFileForRead(const Twine &Name) {
295 int FD;
296297 SmallString<256> RealName, Storage;
297 if (std::error_code EC = sys::fs::openFileForRead(
298 adjustPath(Name, Storage), FD, sys::fs::OF_None, &RealName))
299 return EC;
300 return std::unique_ptr(new RealFile(FD, Name.str(), RealName.str()));
298 Expected FDOrErr = sys::fs::openNativeFileForRead(
299 adjustPath(Name, Storage), sys::fs::OF_None, &RealName);
300 if (!FDOrErr)
301 return errorToErrorCode(FDOrErr.takeError());
302 return std::unique_ptr(
303 new RealFile(*FDOrErr, Name.str(), RealName.str()));
301304 }
302305
303306 llvm::ErrorOr RealFileSystem::getCurrentWorkingDirectory() const {
733733 return getStatus(FileHandle, Result);
734734 }
735735
736 std::error_code status(file_t FileHandle, file_status &Result) {
737 return getStatus(FileHandle, Result);
738 }
739
736740 unsigned getUmask() {
737741 return 0;
738742 }
779783 return std::error_code();
780784 }
781785
782 std::error_code mapped_file_region::init(int FD, uint64_t Offset,
783 mapmode Mode) {
786 std::error_code mapped_file_region::init(sys::fs::file_t OrigFileHandle,
787 uint64_t Offset, mapmode Mode) {
784788 this->Mode = Mode;
785 HANDLE OrigFileHandle = reinterpret_cast(_get_osfhandle(FD));
786789 if (OrigFileHandle == INVALID_HANDLE_VALUE)
787790 return make_error_code(errc::bad_file_descriptor);
788791
849852 return std::error_code();
850853 }
851854
852 mapped_file_region::mapped_file_region(int fd, mapmode mode, size_t length,
853 uint64_t offset, std::error_code &ec)
855 mapped_file_region::mapped_file_region(sys::fs::file_t fd, mapmode mode,
856 size_t length, uint64_t offset,
857 std::error_code &ec)
854858 : Size(length), Mapping() {
855859 ec = init(fd, offset, mode);
856860 if (ec)
12001204 return Result;
12011205 }
12021206
1203 void closeFile(file_t &F) {
1204 ::CloseHandle(F);
1207 file_t convertFDToNativeFile(int FD) {
1208 return reinterpret_cast(::_get_osfhandle(FD));
1209 }
1210
1211 file_t getStdinHandle() { return ::GetStdHandle(STD_INPUT_HANDLE); }
1212 file_t getStdoutHandle() { return ::GetStdHandle(STD_OUTPUT_HANDLE); }
1213 file_t getStderrHandle() { return ::GetStdHandle(STD_ERROR_HANDLE); }
1214
1215 std::error_code readNativeFileImpl(file_t FileHandle, char *BufPtr, size_t BytesToRead,
1216 size_t *BytesRead, OVERLAPPED *Overlap) {
1217 // ReadFile can only read 2GB at a time. The caller should check the number of
1218 // bytes and read in a loop until termination.
1219 DWORD BytesToRead32 =
1220 std::min(size_t(std::numeric_limits::max()), BytesToRead);
1221 DWORD BytesRead32 = 0;
1222 bool Success =
1223 ::ReadFile(FileHandle, BufPtr, BytesToRead32, &BytesRead32, Overlap);
1224 *BytesRead = BytesRead32;
1225 if (!Success) {
1226 DWORD Err = ::GetLastError();
1227 // Pipe EOF is not an error.
1228 if (Err == ERROR_BROKEN_PIPE)
1229 return std::error_code();
1230 return mapWindowsError(Err);
1231 }
1232 return std::error_code();
1233 }
1234
1235 std::error_code readNativeFile(file_t FileHandle, MutableArrayRef Buf,
1236 size_t *BytesRead) {
1237 return readNativeFileImpl(FileHandle, Buf.data(), Buf.size(), BytesRead,
1238 /*Overlap=*/nullptr);
1239 }
1240
1241 std::error_code readNativeFileSlice(file_t FileHandle,
1242 MutableArrayRef Buf, size_t Offset) {
1243 char *BufPtr = Buf.data();
1244 size_t BytesLeft = Buf.size();
1245
1246 while (BytesLeft) {
1247 uint64_t CurOff = Buf.size() - BytesLeft + Offset;
1248 OVERLAPPED Overlapped = {};
1249 Overlapped.Offset = uint32_t(CurOff);
1250 Overlapped.OffsetHigh = uint32_t(uint64_t(CurOff) >> 32);
1251
1252 size_t BytesRead = 0;
1253 if (auto EC = readNativeFileImpl(FileHandle, BufPtr, BytesLeft, &BytesRead,
1254 &Overlapped))
1255 return EC;
1256
1257 // Once we reach EOF, zero the remaining bytes in the buffer.
1258 if (BytesRead == 0) {
1259 memset(BufPtr, 0, BytesLeft);
1260 break;
1261 }
1262 BytesLeft -= BytesRead;
1263 BufPtr += BytesRead;
1264 }
1265 return std::error_code();
1266 }
1267
1268 std::error_code closeFile(file_t &F) {
1269 file_t TmpF = F;
12051270 F = kInvalidFile;
1271 if (!::CloseHandle(TmpF))
1272 return mapWindowsError(::GetLastError());
1273 return std::error_code();
12061274 }
12071275
12081276 std::error_code remove_directories(const Twine &path, bool IgnoreErrors) {
177177 InstrumentationMap::FunctionAddressReverseMap &FunctionIds) {
178178 std::error_code EC;
179179 sys::fs::mapped_file_region MappedFile(
180 Fd, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0, EC);
180 sys::fs::convertFDToNativeFile(Fd),
181 sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0, EC);
181182 if (EC)
182183 return make_error(
183184 Twine("Failed memory-mapping file '") + Filename + "'.", EC);
271271
272272 std::error_code EC;
273273 sys::fs::mapped_file_region MappedFile(
274 Fd, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0, EC);
274 sys::fs::convertFDToNativeFile(Fd),
275 sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0, EC);
275276 if (EC)
276277 return make_error(
277278 Twine("Cannot mmap profile '") + Filename + "'", EC);
390390 // Map the opened file into memory and use a StringRef to access it later.
391391 std::error_code EC;
392392 sys::fs::mapped_file_region MappedFile(
393 Fd, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0, EC);
393 sys::fs::convertFDToNativeFile(Fd),
394 sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0, EC);
394395 if (EC) {
395396 return make_error(
396397 Twine("Cannot read log from '") + Filename + "'", EC);
3434
3535 static CommandRegistration Unused(&Dump, []() -> Error {
3636 // Open the file provided.
37 int Fd;
38 if (auto EC = sys::fs::openFileForRead(DumpInput, Fd))
39 return createStringError(EC, "Cannot open file '%s' for read.",
40 DumpInput.c_str());
37 auto FDOrErr = sys::fs::openNativeFileForRead(DumpInput);
38 if (!FDOrErr)
39 return FDOrErr.takeError();
4140
4241 uint64_t FileSize;
4342 if (auto EC = sys::fs::file_size(DumpInput, FileSize))
4645
4746 std::error_code EC;
4847 sys::fs::mapped_file_region MappedFile(
49 Fd, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0, EC);
48 *FDOrErr, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0,
49 EC);
50 sys::fs::closeFile(*FDOrErr);
5051
5152 DataExtractor DE(StringRef(MappedFile.data(), MappedFile.size()), true, 8);
5253 uint32_t OffsetPtr = 0;
148148 EXPECT_FALSE(sys::fs::openFileForRead(TestPath.c_str(), TestFD));
149149 }
150150
151 ErrorOr Buf =
152 MemoryBuffer::getOpenFileSlice(TestFD, TestPath.c_str(),
153 40000, // Size
154 80000 // Offset
155 );
151 ErrorOr Buf = MemoryBuffer::getOpenFileSlice(
152 sys::fs::convertFDToNativeFile(TestFD), TestPath.c_str(),
153 40000, // Size
154 80000 // Offset
155 );
156156
157157 std::error_code EC = Buf.getError();
158158 EXPECT_FALSE(EC);
10831083 std::error_code EC;
10841084 StringRef Val("hello there");
10851085 {
1086 fs::mapped_file_region mfr(FileDescriptor,
1086 fs::mapped_file_region mfr(fs::convertFDToNativeFile(FileDescriptor),
10871087 fs::mapped_file_region::readwrite, Size, 0, EC);
10881088 ASSERT_NO_ERROR(EC);
10891089 std::copy(Val.begin(), Val.end(), mfr.data());
10981098 int FD;
10991099 EC = fs::openFileForRead(Twine(TempPath), FD);
11001100 ASSERT_NO_ERROR(EC);
1101 fs::mapped_file_region mfr(FD, fs::mapped_file_region::readonly, Size, 0, EC);
1101 fs::mapped_file_region mfr(fs::convertFDToNativeFile(FD),
1102 fs::mapped_file_region::readonly, Size, 0, EC);
11021103 ASSERT_NO_ERROR(EC);
11031104
11041105 // Verify content
11051106 EXPECT_EQ(StringRef(mfr.const_data()), Val);
11061107
11071108 // Unmap temp file
1108 fs::mapped_file_region m(FD, fs::mapped_file_region::readonly, Size, 0, EC);
1109 fs::mapped_file_region m(fs::convertFDToNativeFile(FD),
1110 fs::mapped_file_region::readonly, Size, 0, EC);
11091111 ASSERT_NO_ERROR(EC);
11101112 ASSERT_EQ(close(FD), 0);
11111113 }
5151 };
5252
5353 bool FDHasContent(int FD, StringRef Content) {
54 auto Buffer = MemoryBuffer::getOpenFile(FD, "", -1);
54 auto Buffer =
55 MemoryBuffer::getOpenFile(sys::fs::convertFDToNativeFile(FD), "", -1);
5556 assert(Buffer);
5657 return Buffer.get()->getBuffer() == Content;
5758 }
145146 std::error_code EC;
146147 ASSERT_NO_ERROR(fs::openFileForRead(TargetFileName, TargetFD));
147148 ScopedFD X(TargetFD);
148 sys::fs::mapped_file_region MFR(
149 TargetFD, sys::fs::mapped_file_region::readonly, 10, 0, EC);
149 sys::fs::mapped_file_region MFR(sys::fs::convertFDToNativeFile(TargetFD),
150 sys::fs::mapped_file_region::readonly, 10,
151 0, EC);
150152 ASSERT_FALSE(EC);
151153
152154 ASSERT_NO_ERROR(fs::rename(SourceFileName, TargetFileName));