[flang][runtime] Fix WRITE after OPEN(.., ACCESS="APPEND")

The initial size of the file was not being captured as the file position
on which the first output buffer should be framed.

Differential Revision: https://reviews.llvm.org/D127029
This commit is contained in:
Peter Klausler 2022-06-01 15:32:08 -07:00
parent dfcccc6dee
commit 9a163ffe1a
2 changed files with 12 additions and 7 deletions

View File

@ -132,7 +132,7 @@ void OpenFile::Open(OpenStatus status, std::optional<Action> action,
RUNTIME_CHECK(handler, action.has_value());
pending_.reset();
if (position == Position::Append && !RawSeekToEnd()) {
handler.SignalErrno();
handler.SignalError(IostatOpenBadAppend);
}
isTerminal_ = ::isatty(fd_) == 1;
mayRead_ = *action != Action::Write;

View File

@ -137,7 +137,7 @@ void ExternalFileUnit::OpenUnit(std::optional<OpenStatus> status,
"OPEN(UNIT=%d,ACCESS='DIRECT',RECL=%jd): record length is invalid",
unitNumber(), static_cast<std::intmax_t>(*openRecl));
} else if (totalBytes && (*totalBytes % *openRecl != 0)) {
handler.SignalError(IostatOpenBadAppend,
handler.SignalError(IostatOpenBadRecl,
"OPEN(UNIT=%d,ACCESS='DIRECT',RECL=%jd): record length is not an "
"even divisor of the file size %jd",
unitNumber(), static_cast<std::intmax_t>(*openRecl),
@ -150,12 +150,17 @@ void ExternalFileUnit::OpenUnit(std::optional<OpenStatus> status,
if (totalBytes && access == Access::Direct && openRecl.value_or(0) > 0) {
endfileRecordNumber = 1 + (*totalBytes / *openRecl);
}
if (position == Position::Append && access != Access::Stream) {
if (!endfileRecordNumber) {
// Fake it so that we can backspace relative from the end
endfileRecordNumber = std::numeric_limits<std::int64_t>::max() - 2;
if (position == Position::Append) {
if (totalBytes) {
frameOffsetInFile_ = *totalBytes;
}
if (access != Access::Stream) {
if (!endfileRecordNumber) {
// Fake it so that we can backspace relative from the end
endfileRecordNumber = std::numeric_limits<std::int64_t>::max() - 2;
}
currentRecordNumber = *endfileRecordNumber;
}
currentRecordNumber = *endfileRecordNumber;
}
}