Skip to content

[SR-14953] Data.write(to:) fails when writing to /dev/stdout #3207

Closed
@weissi

Description

@weissi
Previous ID SR-14953
Radar rdar://problem/80949531
Original Reporter @weissi
Type Bug
Environment

5.4/main docker image

Additional Detail from JIRA
Votes 0
Component/s Foundation
Labels Bug
Assignee None
Priority Medium

md5: 98334e709b9a35bb96b5b5e9f20f864e

Issue Description:

try Data("hello".utf8).write(to: URL(fileURLWithPath: "/dev/stdout"))

will fail on Linux with

NSError = domain: nil - code: 14987979559889010706 {
  Foundation.NSObject = {}
  _domain = "NSCocoaErrorDomain"
  _code = 512
  _userInfo = 1 key/value pair {
    [0] = {
      key = "NSUnderlyingError"
      value = domain: nil - code: 14987979559889010706 {
        Foundation.NSObject = {}
        _domain = "NSPOSIXErrorDomain"
        _code = 22
        _userInfo = nil
      }
    }
  }
}

Or a more comprehensive program

import Foundation

let target = CommandLine.arguments.dropFirst().first ?? "/dev/stdout"
do {
    try Data("hello".utf8).write(to: URL(fileURLWithPath: target))
} catch {
    print("ERROR: \(error)")
}

when run under Linux will print

helloERROR: Error Domain=NSCocoaErrorDomain Code=512 "(null)"

note how it actually succeeds in writing the data.

As of osstatus.com, the error is NSFileWriteUnknownError.

The problem seems to be that we call fsync on the file descriptor after the write which isn't valid for most devices:

openat(AT_FDCWD, "/dev/stdout", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
write(3, "hello", 5hello)                    = 5
fsync(3)                                = -1 EINVAL (Invalid argument)

probably originating from here: https://github.com/apple/swift-corelibs-foundation/blob/cc5fc93a9946e82d659f79e1bd991b96eba3fcdf/Sources/Foundation/NSData.swift#L446

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions