| 1093 | } |
| 1094 | |
| 1095 | Result<FileDescriptor> FileOpenWritable(const PlatformFilename& file_name, |
| 1096 | bool write_only, bool truncate, bool append) { |
| 1097 | FileDescriptor fd; |
| 1098 | |
| 1099 | #if defined(_WIN32) |
| 1100 | DWORD desired_access = GENERIC_WRITE; |
| 1101 | DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE; |
| 1102 | DWORD creation_disposition = OPEN_ALWAYS; |
| 1103 | |
| 1104 | if (truncate) { |
| 1105 | creation_disposition = CREATE_ALWAYS; |
| 1106 | } |
| 1107 | |
| 1108 | if (!write_only) { |
| 1109 | desired_access |= GENERIC_READ; |
| 1110 | } |
| 1111 | |
| 1112 | HANDLE file_handle = |
| 1113 | CreateFileW(file_name.ToNative().c_str(), desired_access, share_mode, NULL, |
| 1114 | creation_disposition, FILE_ATTRIBUTE_NORMAL, NULL); |
| 1115 | if (file_handle == INVALID_HANDLE_VALUE) { |
| 1116 | return IOErrorFromWinError(GetLastError(), "Failed to open local file '", |
| 1117 | file_name.ToString(), "'"); |
| 1118 | } |
| 1119 | |
| 1120 | int ret = _open_osfhandle(reinterpret_cast<intptr_t>(file_handle), |
| 1121 | _O_RDONLY | _O_BINARY | _O_NOINHERIT); |
| 1122 | if (ret == -1) { |
| 1123 | CloseHandle(file_handle); |
| 1124 | return IOErrorFromErrno(errno, "Failed to open local file '", file_name.ToString(), |
| 1125 | "'"); |
| 1126 | } |
| 1127 | fd = FileDescriptor(ret); |
| 1128 | #else |
| 1129 | int oflag = O_CREAT; |
| 1130 | |
| 1131 | if (truncate) { |
| 1132 | oflag |= O_TRUNC; |
| 1133 | } |
| 1134 | if (append) { |
| 1135 | oflag |= O_APPEND; |
| 1136 | } |
| 1137 | |
| 1138 | if (write_only) { |
| 1139 | oflag |= O_WRONLY; |
| 1140 | } else { |
| 1141 | oflag |= O_RDWR; |
| 1142 | } |
| 1143 | |
| 1144 | int ret; |
| 1145 | do { |
| 1146 | ret = open(file_name.ToNative().c_str(), oflag, 0666); |
| 1147 | } while (ret == -1 && errno == EINTR); |
| 1148 | if (ret == -1) { |
| 1149 | return IOErrorFromErrno(errno, "Failed to open local file '", file_name.ToString(), |
| 1150 | "'"); |
| 1151 | } |
| 1152 | fd = FileDescriptor(ret); |
no test coverage detected