@@ -34,7 +34,9 @@ ArgsToFrontendInputsConverter::ArgsToFrontendInputsConverter(
3434 DiagnosticEngine &diags, const ArgList &args)
3535 : Diags(diags), Args(args),
3636 FilelistPathArg(args.getLastArg(options::OPT_filelist)),
37- PrimaryFilelistPathArg(args.getLastArg(options::OPT_primary_filelist)) {}
37+ PrimaryFilelistPathArg(args.getLastArg(options::OPT_primary_filelist)),
38+ BadFileDescriptorRetryCountArg(
39+ args.getLastArg(options::OPT_bad_file_descriptor_retry_count)) {}
3840
3941Optional<FrontendInputsAndOutputs> ArgsToFrontendInputsConverter::convert (
4042 SmallVectorImpl<std::unique_ptr<llvm::MemoryBuffer>> *buffers) {
@@ -118,8 +120,26 @@ bool ArgsToFrontendInputsConverter::forAllFilesInFilelist(
118120 if (!pathArg)
119121 return false ;
120122 StringRef path = pathArg->getValue ();
121- llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> filelistBufferOrError =
122- llvm::MemoryBuffer::getFile (path);
123+
124+ // Honor -bad-file-descriptor-retry-count from the argument list
125+ unsigned RetryCount = 0 ;
126+ if (BadFileDescriptorRetryCountArg &&
127+ StringRef (BadFileDescriptorRetryCountArg->getValue ())
128+ .getAsInteger (10 ,RetryCount)) {
129+ Diags.diagnose (SourceLoc (), diag::error_invalid_arg_value,
130+ BadFileDescriptorRetryCountArg->getAsString (Args),
131+ BadFileDescriptorRetryCountArg->getValue ());
132+ return true ;
133+ }
134+
135+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> filelistBufferOrError = nullptr ;
136+ for (unsigned I = 0 ; I < RetryCount + 1 ; ++I) {
137+ filelistBufferOrError = llvm::MemoryBuffer::getFile (path);
138+ if (filelistBufferOrError)
139+ break ;
140+ if (filelistBufferOrError.getError ().value () != EBADF)
141+ break ;
142+ }
123143 if (!filelistBufferOrError) {
124144 Diags.diagnose (SourceLoc (), diag::cannot_open_file, path,
125145 filelistBufferOrError.getError ().message ());
0 commit comments