[llvm] [flang-rt] Fix file opening in APPEND mode on Windows (PR #186144)
David Truby via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 12 08:21:07 PDT 2026
https://github.com/DavidTruby created https://github.com/llvm/llvm-project/pull/186144
Opening files with APPEND on Windows currently opens at the start of the file. This commit fixes this so that the position in the file is set correctly.
Fixes: #183356
>From f6e7fc045db9fb9bcb2b69aef053860370a359fa Mon Sep 17 00:00:00 2001
From: David Truby <david.truby at arm.com>
Date: Mon, 9 Mar 2026 15:23:44 +0000
Subject: [PATCH] [flang-rt] Fix file opening in APPEND mode on Windows
Opening files with APPEND on Windows currently opens at the start of the
file. This commit fixes this so that the position in the file is set
correctly.
Fixes: #183356
---
flang-rt/lib/runtime/file.cpp | 8 +++--
flang-rt/unittests/Runtime/ExternalIOTest.cpp | 35 +++++++++++++++++++
2 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/flang-rt/lib/runtime/file.cpp b/flang-rt/lib/runtime/file.cpp
index 1122f1ee43d88..22cd57662b8ce 100644
--- a/flang-rt/lib/runtime/file.cpp
+++ b/flang-rt/lib/runtime/file.cpp
@@ -160,8 +160,12 @@ void OpenFile::Open(OpenStatus status, common::optional<Action> action,
mayPosition_ = S_ISREG(buf.st_mode);
knownSize_ = buf.st_size;
}
-#else // TODO: _WIN32
- mayPosition_ = true;
+#else // _WIN32
+ struct _stat64 buf;
+ if (fd_ >= 0 && ::_fstat64(fd_, &buf) == 0) {
+ mayPosition_ = S_IFREG & buf.st_mode;
+ knownSize_ = buf.st_size;
+ }
#endif
} else {
knownSize_ = 0;
diff --git a/flang-rt/unittests/Runtime/ExternalIOTest.cpp b/flang-rt/unittests/Runtime/ExternalIOTest.cpp
index 82c3fc38ef161..5f9987e817276 100644
--- a/flang-rt/unittests/Runtime/ExternalIOTest.cpp
+++ b/flang-rt/unittests/Runtime/ExternalIOTest.cpp
@@ -13,9 +13,11 @@
#include "CrashHandlerFixture.h"
#include "gtest/gtest.h"
#include "flang-rt/runtime/descriptor.h"
+#include "flang/Runtime/extensions.h"
#include "flang/Runtime/io-api.h"
#include "flang/Runtime/main.h"
#include "flang/Runtime/stop.h"
+#include <cstdio>
#include <cstring>
#include <string_view>
@@ -952,6 +954,39 @@ TEST(ExternalIOTests, BigUnitNumbers) {
}
}
+TEST(ExternalIOTests, OpenAppend) {
+ FILE *file{std::fopen("openappend", "w")};
+ std::fprintf(file, "foo");
+ std::fclose(file);
+
+ // OPEN(10,POSITION='APPEND')
+ Cookie io{IONAME(BeginOpenUnit)(10, __FILE__, __LINE__)};
+ ASSERT_TRUE(IONAME(SetFile)(io, "openappend", 10)) << "SetFile(openappend)";
+ ASSERT_TRUE(IONAME(SetPosition)(io, "APPEND", 6)) << "SetPosition(APPEND)";
+ ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+ << "EndIoStatement() for Open";
+ // FTELL(10)
+ ASSERT_EQ(RTNAME(Ftell)(10), 3u);
+ // CLOSE(10)
+ io = IONAME(BeginClose)(10, __FILE__, __LINE__);
+ ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+ << "EndIoStatement() for Close";
+
+ // OPEN(10,POSITION='APPEND')
+ io = IONAME(BeginOpenUnit)(10, __FILE__, __LINE__);
+ ASSERT_TRUE(IONAME(SetFile)(io, "openappend", 10)) << "SetFile(openappend)";
+ ASSERT_TRUE(IONAME(SetAccess)(io, "APPEND", 6)) << "SetAccess(APPEND)";
+ ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+ << "EndIoStatement() for Open";
+ // FTELL(10)
+ ASSERT_EQ(RTNAME(Ftell)(10), 3u);
+ // CLOSE(10)
+ io = IONAME(BeginClose)(10, __FILE__, __LINE__);
+ ASSERT_TRUE(IONAME(SetStatus)(io, "DELETE", 6)) << "SetStatus(DELETE)";
+ ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+ << "EndIoStatement() for Close";
+}
+
TEST(ExternalIOTests, OpenNewExtant) {
// OPEN(10,STATUS='REPLACE')
Cookie io{IONAME(BeginOpenUnit)(10, __FILE__, __LINE__)};
More information about the llvm-commits
mailing list