- return error_code::success();
-}
-
-error_code openFileForWrite(const Twine &Name, int &ResultFD,
- sys::fs::OpenFlags Flags, unsigned Mode) {
- // Verify that we don't have both "append" and "excl".
- assert((!(Flags & sys::fs::F_Excl) || !(Flags & sys::fs::F_Append)) &&
- "Cannot specify both 'excl' and 'append' file creation flags!");
-
- int OpenFlags = O_CREAT;
+#ifndef O_CLOEXEC
+ if (!(Flags & OF_ChildInherit)) {
+ int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC);
+ (void)r;
+ assert(r == 0 && "fcntl(F_SETFD, FD_CLOEXEC) failed");
+ }
+#endif
+ return std::error_code();
+}
+
+Expected<int> openNativeFile(const Twine &Name, CreationDisposition Disp,
+ FileAccess Access, OpenFlags Flags,
+ unsigned Mode) {
+
+ int FD;
+ std::error_code EC = openFile(Name, FD, Disp, Access, Flags, Mode);
+ if (EC)
+ return errorCodeToError(EC);
+ return FD;
+}
+
+std::error_code openFileForRead(const Twine &Name, int &ResultFD,
+ OpenFlags Flags,
+ SmallVectorImpl<char> *RealPath) {
+ std::error_code EC =
+ openFile(Name, ResultFD, CD_OpenExisting, FA_Read, Flags, 0666);
+ if (EC)
+ return EC;
+
+ // Attempt to get the real name of the file, if the user asked
+ if(!RealPath)
+ return std::error_code();
+ RealPath->clear();
+#if defined(F_GETPATH)
+ // When F_GETPATH is availble, it is the quickest way to get
+ // the real path name.
+ char Buffer[MAXPATHLEN];
+ if (::fcntl(ResultFD, F_GETPATH, Buffer) != -1)
+ RealPath->append(Buffer, Buffer + strlen(Buffer));
+#else
+ char Buffer[PATH_MAX];
+ if (hasProcSelfFD()) {
+ char ProcPath[64];
+ snprintf(ProcPath, sizeof(ProcPath), "/proc/self/fd/%d", ResultFD);
+ ssize_t CharCount = ::readlink(ProcPath, Buffer, sizeof(Buffer));
+ if (CharCount > 0)
+ RealPath->append(Buffer, Buffer + CharCount);
+ } else {
+ SmallString<128> Storage;
+ StringRef P = Name.toNullTerminatedStringRef(Storage);