Signals in Swift

Here’s an idiomatic Swift example demonstrating the concept of handling signals:

import Foundation

// Create a signal handler function
func signalHandler(signal: Int32) -> Void {
    print("\nReceived signal: \(signal)")
    exit(0)
}

// Register the signal handler for SIGINT and SIGTERM
signal(SIGINT, signalHandler)
signal(SIGTERM, signalHandler)

print("Awaiting signal...")

// Keep the program running
RunLoop.main.run()

This Swift program demonstrates how to handle Unix signals, specifically SIGINT (interrupt signal, usually triggered by Ctrl+C) and SIGTERM (termination signal).

Let’s break down the code:

  1. We import the Foundation framework, which provides the necessary functionality for signal handling in Swift.

  2. We define a signalHandler function that takes an Int32 parameter representing the signal. This function prints the received signal and then exits the program.

  3. We use the signal() function to register our signalHandler for both SIGINT and SIGTERM. This tells the system to call our handler function when these signals are received.

  4. We print a message indicating that the program is waiting for a signal.

  5. Finally, we use RunLoop.main.run() to keep the program running indefinitely, waiting for signals.

To run this program:

  1. Save the code in a file named SignalHandling.swift.
  2. Open a terminal and navigate to the directory containing the file.
  3. Compile and run the code using the Swift compiler:
$ swift SignalHandling.swift
Awaiting signal...

The program will continue running until it receives a signal. You can test it by pressing Ctrl+C in the terminal, which will send a SIGINT:

$ swift SignalHandling.swift
Awaiting signal...
^C
Received signal: 2

This example demonstrates how to handle signals in Swift, which is useful for creating more robust command-line tools or server applications that need to respond to system events or gracefully shut down when requested.

Note that Swift’s approach to signal handling is somewhat simpler than Go’s channel-based approach. Swift uses a more traditional callback-style API, which is common in many systems programming contexts.