Skip to content

Instantly share code, notes, and snippets.

@leptos-null
Created May 27, 2023 03:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leptos-null/de904e0a0d8cc05de1cb55a543ea9afa to your computer and use it in GitHub Desktop.
Save leptos-null/de904e0a0d8cc05de1cb55a543ea9afa to your computer and use it in GitHub Desktop.
Swift function to redirect stdout. Helpful for using print in environments where stdout is not easily accessible
import Foundation
func redirectStdout(to path: String) throws {
let (openResult, posixErrorCode) = path.withCString {
// idea thanks to https://github.com/leptos-null/ClassDumpRuntime/blob/31e3601/classdumpctl/main.m#L456-L459
// error checking thanks to https://github.com/leptos-null/Forest/blob/ba4b89a/Shared/Tar.swift#L172-L174
let result = open($0, O_WRONLY | O_CREAT | O_TRUNC, 0o644)
let globalError = errno // copy errno since it may change before we access it again later
return (result, globalError)
}
guard openResult >= 0 else {
throw NSError(domain: NSPOSIXErrorDomain, code: Int(posixErrorCode))
}
let dupStatus = dup2(openResult, STDOUT_FILENO)
let globalError = errno // copy errno since it may change before we access it again later
guard dupStatus >= 0 else {
throw NSError(domain: NSPOSIXErrorDomain, code: Int(globalError))
}
}
@leptos-null
Copy link
Author

Testing:

try! redirectStdout(to: "/tmp/app_logs.txt")

let runLoop: RunLoop = .current
let timerCancellable = Timer.publish(every: 0.5, on: runLoop, in: .default)
    .autoconnect()
    .sink { pubDate in
        print("Hello at \(pubDate.formatted(date: .omitted, time: .standard))")
    }

runLoop.run(mode: .default, before: Date(timeIntervalSinceNow: 8))
timerCancellable.cancel()

and running tail -f /tmp/app_logs.txt in a shell.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment