Trap exit code (SIGINT, SIGTERM etc) in a Swift Package Executable CLI

December 11, 20222 min read#swift, #swift-package-manager

The Problem

When building an executable CLI product using swift package, especially ones with long running tasks, users can exit the script at anytime by sending exit code to the process, for example, by tapping CTL+C or execute killall command.

Sometimes the CLI needs to trap such signals to do cleanup works. For Example, if the CLI is writing data continuously into a file, it might need to close the file properly on exit so that the file will not be corrupted.

The Solution

Using signal

Swift Foundation provides a native signal API to trigger a signal handler whenever a specific signal code is raised by the system.

@main
struct ScreenCaptureCLI {
    static func main() async throws {
        let screenRecorder = ScreenRecorder()
        
        signal(SIGINT) { code in
            print("Code: \(code)")
            screenRecorder.stop()
            exit(code)
        }
        
        await screenRecorder.start()
    }
}

Using BlueSignals package

BlueSignals package provides covenient APIs to trap and handle platform signals by wrapping platform-specific APIs.

import Signals

...

let server: SomeServer = ...

Signals.trap(signal: .int) { signal in

	server.shutdownServer()
}

server.run()
Quick Drop logo

Profile picture

Personal blog by An Tran. I'm focusing on creating useful apps.
#Swift #Kotlin #Mobile #MachineLearning #Minimalist


© An Tran - 2024