2026-01-24 23:40:22 +01:00
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > signal - Wren-CLI Manual</ title >
< link rel = "stylesheet" href = "../css/style.css" >
</ head >
< body >
< button class = "mobile-menu-toggle" > Menu</ button >
< div class = "container" >
< aside class = "sidebar" >
< div class = "sidebar-header" >
< h1 >< a href = "../index.html" > Wren-CLI</ a ></ h1 >
< div class = "version" > v0.4.0</ div >
</ div >
< nav class = "sidebar-nav" >
< div class = "section" >
< span class = "section-title" > Getting Started</ span >
< ul >
< li >< a href = "../getting-started/index.html" > Overview</ a ></ li >
< li >< a href = "../getting-started/installation.html" > Installation</ a ></ li >
< li >< a href = "../getting-started/first-script.html" > First Script</ a ></ li >
< li >< a href = "../getting-started/repl.html" > Using the REPL</ a ></ li >
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > Language</ span >
< ul >
< li >< a href = "../language/index.html" > Syntax Overview</ a ></ li >
< li >< a href = "../language/classes.html" > Classes</ a ></ li >
< li >< a href = "../language/methods.html" > Methods</ a ></ li >
< li >< a href = "../language/control-flow.html" > Control Flow</ a ></ li >
< li >< a href = "../language/fibers.html" > Fibers</ a ></ li >
< li >< a href = "../language/modules.html" > Modules</ a ></ li >
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > API Reference</ span >
< ul >
< li >< a href = "index.html" > Overview</ a ></ li >
2026-01-25 04:58:39 +01:00
< li >< a href = "string.html" > String</ a ></ li >
< li >< a href = "number.html" > Num</ a ></ li >
2026-01-25 13:09:28 +01:00
< li >< a href = "argparse.html" > argparse</ a ></ li >
2026-01-24 23:40:22 +01:00
< li >< a href = "base64.html" > base64</ a ></ li >
< li >< a href = "crypto.html" > crypto</ a ></ li >
2026-01-25 13:09:28 +01:00
< li >< a href = "dataset.html" > dataset</ a ></ li >
2026-01-24 23:40:22 +01:00
< li >< a href = "datetime.html" > datetime</ a ></ li >
2026-01-25 13:09:28 +01:00
< li >< a href = "dns.html" > dns</ a ></ li >
< li >< a href = "env.html" > env</ a ></ li >
< li >< a href = "fswatch.html" > fswatch</ a ></ li >
< li >< a href = "html.html" > html</ a ></ li >
< li >< a href = "http.html" > http</ a ></ li >
2026-01-24 23:40:22 +01:00
< li >< a href = "io.html" > io</ a ></ li >
2026-01-25 13:09:28 +01:00
< li >< a href = "jinja.html" > jinja</ a ></ li >
< li >< a href = "json.html" > json</ a ></ li >
< li >< a href = "markdown.html" > markdown</ a ></ li >
2026-01-24 23:40:22 +01:00
< li >< a href = "math.html" > math</ a ></ li >
2026-01-25 13:09:28 +01:00
< li >< a href = "net.html" > net</ a ></ li >
< li >< a href = "os.html" > os</ a ></ li >
< li >< a href = "pathlib.html" > pathlib</ a ></ li >
< li >< a href = "regex.html" > regex</ a ></ li >
< li >< a href = "scheduler.html" > scheduler</ a ></ li >
< li >< a href = "signal.html" class = "active" > signal</ a ></ li >
< li >< a href = "sqlite.html" > sqlite</ a ></ li >
< li >< a href = "subprocess.html" > subprocess</ a ></ li >
< li >< a href = "sysinfo.html" > sysinfo</ a ></ li >
< li >< a href = "tempfile.html" > tempfile</ a ></ li >
< li >< a href = "timer.html" > timer</ a ></ li >
< li >< a href = "tls.html" > tls</ a ></ li >
< li >< a href = "udp.html" > udp</ a ></ li >
< li >< a href = "uuid.html" > uuid</ a ></ li >
< li >< a href = "wdantic.html" > wdantic</ a ></ li >
< li >< a href = "web.html" > web</ a ></ li >
< li >< a href = "websocket.html" > websocket</ a ></ li >
2026-01-24 23:40:22 +01:00
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > Tutorials</ span >
< ul >
< li >< a href = "../tutorials/index.html" > Tutorial List</ a ></ li >
2026-01-25 13:09:28 +01:00
< li >< a href = "../tutorials/http-client.html" > HTTP Client</ a ></ li >
< li >< a href = "../tutorials/websocket-chat.html" > WebSocket Chat</ a ></ li >
< li >< a href = "../tutorials/database-app.html" > Database App</ a ></ li >
< li >< a href = "../tutorials/template-rendering.html" > Templates</ a ></ li >
< li >< a href = "../tutorials/cli-tool.html" > CLI Tool</ a ></ li >
2026-01-25 19:02:02 +01:00
< li >< a href = "../tutorials/web-server.html" > Web Server</ a ></ li >
2026-01-24 23:40:22 +01:00
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > How-To Guides</ span >
< ul >
< li >< a href = "../howto/index.html" > How-To List</ a ></ li >
2026-01-25 13:09:28 +01:00
< li >< a href = "../howto/http-requests.html" > HTTP Requests</ a ></ li >
< li >< a href = "../howto/json-parsing.html" > JSON Parsing</ a ></ li >
< li >< a href = "../howto/regex-patterns.html" > Regex Patterns</ a ></ li >
< li >< a href = "../howto/file-operations.html" > File Operations</ a ></ li >
< li >< a href = "../howto/async-operations.html" > Async Operations</ a ></ li >
< li >< a href = "../howto/error-handling.html" > Error Handling</ a ></ li >
2026-01-24 23:40:22 +01:00
</ ul >
</ div >
2026-01-25 19:02:02 +01:00
< div class = "section" >
< span class = "section-title" > Contributing</ span >
< ul >
< li >< a href = "../contributing/index.html" > Overview</ a ></ li >
< li >< a href = "../contributing/module-overview.html" > Module Architecture</ a ></ li >
< li >< a href = "../contributing/pure-wren-module.html" > Pure-Wren Modules</ a ></ li >
< li >< a href = "../contributing/c-backed-module.html" > C-Backed Modules</ a ></ li >
< li >< a href = "../contributing/foreign-classes.html" > Foreign Classes</ a ></ li >
< li >< a href = "../contributing/async-patterns.html" > Async Patterns</ a ></ li >
< li >< a href = "../contributing/testing.html" > Writing Tests</ a ></ li >
< li >< a href = "../contributing/documentation.html" > Documentation</ a ></ li >
</ ul >
</ div >
2026-01-24 23:40:22 +01:00
</ nav >
</ aside >
< main class = "content" >
< nav class = "breadcrumb" >
< a href = "../index.html" > Home</ a >
< span class = "separator" > /</ span >
< a href = "index.html" > API Reference</ a >
< span class = "separator" > /</ span >
< span > signal</ span >
</ nav >
< article >
< h1 > signal</ h1 >
< p > The < code > signal</ code > module provides Unix signal handling capabilities, allowing scripts to trap, ignore, or reset signal handlers.</ p >
< pre >< code > import "signal" for Signal</ code ></ pre >
< h2 > Signal Class</ h2 >
< div class = "class-header" >
< h3 > Signal</ h3 >
< p > Unix signal handling</ p >
</ div >
< h3 > Signal Constants</ h3 >
< table >
< tr >
< th > Constant</ th >
< th > Value</ th >
< th > Description</ th >
</ tr >
< tr >
< td >< code > Signal.SIGHUP</ code ></ td >
< td > 1</ td >
< td > Hangup (terminal closed or controlling process ended)</ td >
</ tr >
< tr >
< td >< code > Signal.SIGINT</ code ></ td >
< td > 2</ td >
< td > Interrupt (Ctrl+C)</ td >
</ tr >
< tr >
< td >< code > Signal.SIGQUIT</ code ></ td >
< td > 3</ td >
< td > Quit (Ctrl+\)</ td >
</ tr >
< tr >
< td >< code > Signal.SIGTERM</ code ></ td >
< td > 15</ td >
< td > Termination request</ td >
</ tr >
< tr >
< td >< code > Signal.SIGUSR1</ code ></ td >
< td > 10</ td >
< td > User-defined signal 1</ td >
</ tr >
< tr >
< td >< code > Signal.SIGUSR2</ code ></ td >
< td > 12</ td >
< td > User-defined signal 2</ td >
</ tr >
</ table >
< h3 > Static Methods</ h3 >
< div class = "method-signature" >
< span class = "method-name" > Signal.trap</ span > (< span class = "param" > signum</ span > , < span class = "param" > fn</ span > )
</ div >
< p > Registers a handler function to be called when the signal is received. The handler will be called each time the signal is received.</ p >
< ul class = "param-list" >
< li >< span class = "param-name" > signum</ span > < span class = "param-type" > (Num)</ span > - Signal number or constant</ li >
< li >< span class = "param-name" > fn</ span > < span class = "param-type" > (Fn)</ span > - Handler function (no arguments)</ li >
</ ul >
< pre >< code > Signal.trap(Signal.SIGINT) {
System.print("Caught Ctrl+C!")
}</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > Signal.ignore</ span > (< span class = "param" > signum</ span > )
</ div >
< p > Ignores the specified signal. The signal will be delivered but have no effect.</ p >
< ul class = "param-list" >
< li >< span class = "param-name" > signum</ span > < span class = "param-type" > (Num)</ span > - Signal number to ignore</ li >
</ ul >
< pre >< code > Signal.ignore(Signal.SIGHUP)</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > Signal.reset</ span > (< span class = "param" > signum</ span > )
</ div >
< p > Resets the signal handler to the default behavior.</ p >
< ul class = "param-list" >
< li >< span class = "param-name" > signum</ span > < span class = "param-type" > (Num)</ span > - Signal number to reset</ li >
</ ul >
< pre >< code > Signal.reset(Signal.SIGINT)</ code ></ pre >
< h2 > Examples</ h2 >
< h3 > Graceful Shutdown</ h3 >
< pre >< code > import "signal" for Signal
import "timer" for Timer
var running = true
Signal.trap(Signal.SIGINT) {
System.print("\nShutting down gracefully...")
running = false
}
Signal.trap(Signal.SIGTERM) {
System.print("\nReceived SIGTERM, shutting down...")
running = false
}
System.print("Server running. Press Ctrl+C to stop.")
while (running) {
Timer.sleep(1000)
}
System.print("Cleanup complete. Goodbye!")</ code ></ pre >
< h3 > Configuration Reload on SIGHUP</ h3 >
< pre >< code > import "signal" for Signal
import "timer" for Timer
import "io" for File
var config = {}
var loadConfig = Fn.new {
System.print("Loading configuration...")
if (File.exists("config.json")) {
var content = File.read("config.json")
System.print("Config loaded: %(content)")
}
}
loadConfig.call()
Signal.trap(Signal.SIGHUP) {
System.print("Received SIGHUP, reloading config...")
loadConfig.call()
}
System.print("Running. Send SIGHUP to reload config.")
while (true) {
Timer.sleep(1000)
}</ code ></ pre >
< h3 > Custom Signal for Debug Dump</ h3 >
< pre >< code > import "signal" for Signal
import "timer" for Timer
import "datetime" for DateTime
var requestCount = 0
var startTime = DateTime.now()
Signal.trap(Signal.SIGUSR1) {
System.print("=== Debug Dump ===")
System.print("Requests handled: %(requestCount)")
var uptime = DateTime.now() - startTime
System.print("Uptime: %(uptime.hours) hours")
System.print("==================")
}
System.print("Send SIGUSR1 for debug info (kill -USR1 pid)")
while (true) {
requestCount = requestCount + 1
Timer.sleep(100)
}</ code ></ pre >
< h3 > Ignoring Signals</ h3 >
< pre >< code > import "signal" for Signal
import "timer" for Timer
Signal.ignore(Signal.SIGINT)
System.print("SIGINT is now ignored. Ctrl+C will not stop this script.")
System.print("Use 'kill -9 pid' to force stop.")
for (i in 1..10) {
System.print("Still running... %(i)")
Timer.sleep(1000)
}
Signal.reset(Signal.SIGINT)
System.print("SIGINT handler restored. Ctrl+C works again.")</ code ></ pre >
< h3 > Multiple Signal Handlers</ h3 >
< pre >< code > import "signal" for Signal
import "timer" for Timer
var shutdownRequested = false
var forceShutdown = false
Signal.trap(Signal.SIGINT) {
if (shutdownRequested) {
System.print("\nForce shutdown!")
forceShutdown = true
} else {
System.print("\nGraceful shutdown requested. Press Ctrl+C again to force.")
shutdownRequested = true
}
}
Signal.trap(Signal.SIGTERM) {
System.print("\nSIGTERM received, shutting down immediately.")
forceShutdown = true
}
System.print("Running... Press Ctrl+C to stop.")
while (!forceShutdown) {
if (shutdownRequested) {
System.print("Cleaning up...")
Timer.sleep(500)
break
}
Timer.sleep(100)
}
System.print("Exited.")</ code ></ pre >
< h3 > Worker Process Control</ h3 >
< pre >< code > import "signal" for Signal
import "timer" for Timer
var paused = false
Signal.trap(Signal.SIGUSR1) {
paused = true
System.print("Worker paused")
}
Signal.trap(Signal.SIGUSR2) {
paused = false
System.print("Worker resumed")
}
System.print("Worker running. SIGUSR1 to pause, SIGUSR2 to resume.")
var count = 0
while (true) {
if (!paused) {
count = count + 1
System.print("Working... %(count)")
}
Timer.sleep(1000)
}</ code ></ pre >
< div class = "admonition note" >
< div class = "admonition-title" > Note</ div >
< p > Signal handling is only available on POSIX systems (Linux, macOS, BSD). On Windows, signal support is limited.</ p >
</ div >
< div class = "admonition warning" >
< div class = "admonition-title" > Warning</ div >
< p > Some signals like SIGKILL (9) and SIGSTOP (19) cannot be trapped or ignored. Attempting to do so will have no effect.</ p >
</ div >
< div class = "admonition tip" >
< div class = "admonition-title" > Tip</ div >
< p > Always implement graceful shutdown handlers for long-running services. Use SIGTERM for clean shutdowns and reserve SIGINT for interactive termination.</ p >
</ div >
</ article >
< footer class = "page-footer" >
2026-01-25 13:09:28 +01:00
< a href = "scheduler.html" class = "prev" > scheduler</ a >
< a href = "sqlite.html" class = "next" > sqlite</ a >
2026-01-24 23:40:22 +01:00
</ footer >
</ main >
</ div >
< script src = "../js/main.js" ></ script >
</ body >
</ html >