Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Sources/AWSLambdaPluginHelper/AWSLambdaPluginHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ struct AWSLambdaPluginHelper {
}

public static func main() async throws {
// Stream output line-by-line; SwiftPM connects the plugin's stdout to a pipe, which the C
// runtime would otherwise block-buffer until the process exits.
enableLineBufferedStdout()

let args = CommandLine.arguments
let helper = AWSLambdaPluginHelper()

Expand Down
41 changes: 41 additions & 0 deletions Sources/AWSLambdaPluginHelper/StandardOutput.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright SwiftAWSLambdaRuntime project authors
// Copyright (c) Amazon.com, Inc. or its affiliates.
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// `stdout` is a libc global `var` (an `extern FILE *`) and so reading it trips the Swift 6
// strict-concurrency check. `@preconcurrency` silences that diagnostic for libc symbols. It is
// confined to this dedicated file — the rest of the target imports libc normally and keeps full
// concurrency checking — to keep the suppression's blast radius as small as possible.
#if os(macOS)
@preconcurrency import Darwin.C
#elseif canImport(Glibc)
@preconcurrency import Glibc
#elseif canImport(Musl)
@preconcurrency import Musl
#elseif os(Windows)
@preconcurrency import ucrt
#else
#error("Unsupported platform")
#endif

/// Switches `stdout` to line buffering.
///
/// SwiftPM runs plugins with stdout connected to a pipe rather than a TTY, so the C runtime
/// block-buffers stdout and the helper's output (and `--help` text) only appears once the process
/// exits. Line buffering makes each printed line stream to the user as it is produced.
///
/// Must be called once, before any output is produced.
func enableLineBufferedStdout() {
setvbuf(stdout, nil, _IOLBF, 0)
}