| 1053 | } |
| 1054 | |
| 1055 | Result<FileDescriptor> FileOpenReadable(const PlatformFilename& file_name) { |
| 1056 | FileDescriptor fd; |
| 1057 | #if defined(_WIN32) |
| 1058 | HANDLE file_handle = CreateFileW(file_name.ToNative().c_str(), GENERIC_READ, |
| 1059 | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, |
| 1060 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); |
| 1061 | if (file_handle == INVALID_HANDLE_VALUE) { |
| 1062 | return IOErrorFromWinError(GetLastError(), "Failed to open local file '", |
| 1063 | file_name.ToString(), "'"); |
| 1064 | } |
| 1065 | int ret = _open_osfhandle(reinterpret_cast<intptr_t>(file_handle), |
| 1066 | _O_RDONLY | _O_BINARY | _O_NOINHERIT); |
| 1067 | if (ret == -1) { |
| 1068 | CloseHandle(file_handle); |
| 1069 | return IOErrorFromErrno(errno, "Failed to open local file '", file_name.ToString(), |
| 1070 | "'"); |
| 1071 | } |
| 1072 | fd = FileDescriptor(ret); |
| 1073 | #else |
| 1074 | int ret; |
| 1075 | do { |
| 1076 | ret = open(file_name.ToNative().c_str(), O_RDONLY); |
| 1077 | } while (ret == -1 && errno == EINTR); |
| 1078 | if (ret == -1) { |
| 1079 | return IOErrorFromErrno(errno, "Failed to open local file '", file_name.ToString(), |
| 1080 | "'"); |
| 1081 | } |
| 1082 | // open(O_RDONLY) succeeds on directories, check for it |
| 1083 | fd = FileDescriptor(ret); |
| 1084 | struct stat st; |
| 1085 | ret = fstat(fd.fd(), &st); |
| 1086 | if (ret == 0 && S_ISDIR(st.st_mode)) { |
| 1087 | return Status::IOError("Cannot open for reading: path '", file_name.ToString(), |
| 1088 | "' is a directory"); |
| 1089 | } |
| 1090 | #endif |
| 1091 | |
| 1092 | return fd; |
| 1093 | } |
| 1094 | |
| 1095 | Result<FileDescriptor> FileOpenWritable(const PlatformFilename& file_name, |
| 1096 | bool write_only, bool truncate, bool append) { |
no test coverage detected