aboutsummaryrefslogtreecommitdiff
path: root/src/syscall
diff options
context:
space:
mode:
authorqmuntal <quimmuntal@gmail.com>2025-10-30 12:36:42 +0100
committerQuim Muntal <quimmuntal@gmail.com>2025-11-04 23:31:35 -0800
commit9f3a108ee0d2f08b4994c4201e54e5a53acbc216 (patch)
tree100b3f7ec147f7b732d0a33ac56c796ef08486fa /src/syscall
parent0e1bd8b5f17e337df0ffb57af03419b96c695fe4 (diff)
downloadgo-9f3a108ee0d2f08b4994c4201e54e5a53acbc216.tar.xz
os: ignore O_TRUNC errors on named pipes and terminal devices on Windows
Prior to Go 1.24, os.OpenFile used to support O_TRUNC on named pipes and terminal devices, even when the truncation was really ignored. This behavior was consistent with Unix semantics. CL 618836 changed the implementation of os.OpenFile on Windows and unintentionally started returning an error when O_TRUNC was used on such files. Fixes #76071 Change-Id: Id10d3d8120ae9aa0548ef05423a172ff4e502ff9 Reviewed-on: https://go-review.googlesource.com/c/go/+/716420 Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Alex Brainman <alex.brainman@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Damien Neil <dneil@google.com> Reviewed-by: Michael Pratt <mpratt@google.com>
Diffstat (limited to 'src/syscall')
-rw-r--r--src/syscall/syscall_windows.go8
-rw-r--r--src/syscall/types_windows.go4
2 files changed, 12 insertions, 0 deletions
diff --git a/src/syscall/syscall_windows.go b/src/syscall/syscall_windows.go
index 817eeb6811..3e63897b6b 100644
--- a/src/syscall/syscall_windows.go
+++ b/src/syscall/syscall_windows.go
@@ -468,6 +468,14 @@ func Open(name string, flag int, perm uint32) (fd Handle, err error) {
if flag&O_TRUNC == O_TRUNC &&
(createmode == OPEN_EXISTING || (createmode == OPEN_ALWAYS && err == ERROR_ALREADY_EXISTS)) {
err = Ftruncate(h, 0)
+ if err == _ERROR_INVALID_PARAMETER {
+ // ERROR_INVALID_PARAMETER means truncation is not supported on this file handle.
+ // Unix's O_TRUNC specification says to ignore O_TRUNC on named pipes and terminal devices.
+ // We do the same here.
+ if t, err1 := GetFileType(h); err1 == nil && (t == FILE_TYPE_PIPE || t == FILE_TYPE_CHAR) {
+ err = nil
+ }
+ }
if err != nil {
CloseHandle(h)
return InvalidHandle, err
diff --git a/src/syscall/types_windows.go b/src/syscall/types_windows.go
index b40b455e7d..3c6d18a850 100644
--- a/src/syscall/types_windows.go
+++ b/src/syscall/types_windows.go
@@ -35,6 +35,10 @@ const (
)
const (
+ _ERROR_INVALID_PARAMETER Errno = 87
+)
+
+const (
// Invented values to support what package os expects.
O_RDONLY = 0x00000
O_WRONLY = 0x00001