| 165 | }; |
| 166 | |
| 167 | static std::error_code |
| 168 | createUniqueEntity(const Twine &Model, int &ResultFD, |
| 169 | SmallVectorImpl<char> &ResultPath, bool MakeAbsolute, |
| 170 | unsigned Mode, FSEntity Type, |
| 171 | sys::fs::OpenFlags Flags = sys::fs::OF_None) { |
| 172 | |
| 173 | // Limit the number of attempts we make, so that we don't infinite loop. E.g. |
| 174 | // "permission denied" could be for a specific file (so we retry with a |
| 175 | // different name) or for the whole directory (retry would always fail). |
| 176 | // Checking which is racy, so we try a number of times, then give up. |
| 177 | std::error_code EC; |
| 178 | for (int Retries = 128; Retries > 0; --Retries) { |
| 179 | sys::fs::createUniquePath(Model, ResultPath, MakeAbsolute); |
| 180 | // Try to open + create the file. |
| 181 | switch (Type) { |
| 182 | case FS_File: { |
| 183 | EC = sys::fs::openFileForReadWrite(Twine(ResultPath.begin()), ResultFD, |
| 184 | sys::fs::CD_CreateNew, Flags, Mode); |
| 185 | if (EC) { |
| 186 | // errc::permission_denied happens on Windows when we try to open a file |
| 187 | // that has been marked for deletion. |
| 188 | if (EC == errc::file_exists || EC == errc::permission_denied) |
| 189 | continue; |
| 190 | return EC; |
| 191 | } |
| 192 | |
| 193 | return std::error_code(); |
| 194 | } |
| 195 | |
| 196 | case FS_Name: { |
| 197 | EC = sys::fs::access(ResultPath.begin(), sys::fs::AccessMode::Exist); |
| 198 | if (EC == errc::no_such_file_or_directory) |
| 199 | return std::error_code(); |
| 200 | if (EC) |
| 201 | return EC; |
| 202 | continue; |
| 203 | } |
| 204 | |
| 205 | case FS_Dir: { |
| 206 | EC = sys::fs::create_directory(ResultPath.begin(), false); |
| 207 | if (EC) { |
| 208 | if (EC == errc::file_exists) |
| 209 | continue; |
| 210 | return EC; |
| 211 | } |
| 212 | return std::error_code(); |
| 213 | } |
| 214 | } |
| 215 | llvm_unreachable("Invalid Type"); |
| 216 | } |
| 217 | return EC; |
| 218 | } |
| 219 | |
| 220 | namespace llvm { |
| 221 | namespace sys { |
no test coverage detected