From: peter klausler Date: Fri, 3 Jul 2020 17:56:08 +0000 (-0700) Subject: [flang] Track known file size, add IsATerminal (ext. I/O work part 5) X-Git-Tag: llvmorg-12-init~1071 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7926969afc63820b123de9d6895c3913befaae1b;p=platform%2Fupstream%2Fllvm.git [flang] Track known file size, add IsATerminal (ext. I/O work part 5) Add a data member knownSize_ and an accessor to allow the size of an external file to be tracked when known. Also add a wrapper for ::isatty() here in the filesystem encapsulation module. These features are needed for the external I/O rework changes still to come. Reviewed By: sscalpone Differential Revision: https://reviews.llvm.org/D83141 --- diff --git a/flang/runtime/file.cpp b/flang/runtime/file.cpp index fdd7ea6..120c1ce 100644 --- a/flang/runtime/file.cpp +++ b/flang/runtime/file.cpp @@ -64,9 +64,11 @@ void OpenFile::Open( if (fd_ >= 0) { return; } + knownSize_.reset(); break; case OpenStatus::New: flags |= O_CREAT | O_EXCL; + knownSize_ = 0; break; case OpenStatus::Scratch: if (path_.get()) { @@ -74,15 +76,18 @@ void OpenFile::Open( path_.reset(); } fd_ = openfile_mkstemp(handler); + knownSize_ = 0; return; case OpenStatus::Replace: flags |= O_CREAT | O_TRUNC; + knownSize_ = 0; break; case OpenStatus::Unknown: if (fd_ >= 0) { return; } flags |= O_CREAT; + knownSize_.reset(); break; } // If we reach this point, we're opening a new file. @@ -104,7 +109,6 @@ void OpenFile::Open( handler.SignalErrno(); } pending_.reset(); - knownSize_.reset(); if (position == Position::Append && !RawSeekToEnd()) { handler.SignalErrno(); } @@ -152,17 +156,14 @@ std::size_t OpenFile::Read(FileOffset at, char *buffer, std::size_t minBytes, if (!Seek(at, handler)) { return 0; } - if (maxBytes < minBytes) { - minBytes = maxBytes; - } + minBytes = std::min(minBytes, maxBytes); std::size_t got{0}; while (got < minBytes) { auto chunk{::read(fd_, buffer + got, maxBytes - got)}; if (chunk == 0) { handler.SignalEnd(); break; - } - if (chunk < 0) { + } else if (chunk < 0) { auto err{errno}; if (err != EAGAIN && err != EWOULDBLOCK && err != EINTR) { handler.SignalError(err); @@ -355,4 +356,6 @@ int OpenFile::PendingResult(const Terminator &terminator, int iostat) { pending_ = New{terminator}(id, iostat, std::move(pending_)); return id; } + +bool IsATerminal(int fd) { return ::isatty(fd); } } // namespace Fortran::runtime::io diff --git a/flang/runtime/file.h b/flang/runtime/file.h index 741a0bc..17a5e91 100644 --- a/flang/runtime/file.h +++ b/flang/runtime/file.h @@ -39,6 +39,7 @@ public: void set_mayPosition(bool yes) { mayPosition_ = yes; } FileOffset position() const { return position_; } bool isTerminal() const { return isTerminal_; } + std::optional knownSize() const { return knownSize_; } bool IsOpen() const { return fd_ >= 0; } void Open(OpenStatus, Position, IoErrorHandler &); @@ -94,5 +95,7 @@ private: int nextId_; OwningPtr pending_; }; + +bool IsATerminal(int fd); } // namespace Fortran::runtime::io #endif // FORTRAN_RUNTIME_FILE_H_