Files
wren/manual/api/signal.html
T
retoor 819bbd5091 feat: add fswatch, sysinfo, and udp demo scripts plus reorder manual sidebar links
Add three new example scripts demonstrating the fswatch, sysinfo, and udp modules with file watching, system metrics, and UDP echo server/client patterns. Reorder the manual API sidebar navigation to list modules alphabetically, removing deprecated entries like websocket, tls, net, json, regex, jinja, os, signal, subprocess, sqlite, and timer while adding argparse, dataset, fswatch, and html.
2026-01-25 12:09:28 +00:00

375 lines
14 KiB
HTML

<!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>
<li><a href="string.html">String</a></li>
<li><a href="number.html">Num</a></li>
<li><a href="argparse.html">argparse</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="dataset.html">dataset</a></li>
<li><a href="datetime.html">datetime</a></li>
<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>
<li><a href="io.html">io</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="json.html">json</a></li>
<li><a href="markdown.html">markdown</a></li>
<li><a href="math.html">math</a></li>
<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>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
<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>
</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>
<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>
</ul>
</div>
</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">
<a href="scheduler.html" class="prev">scheduler</a>
<a href="sqlite.html" class="next">sqlite</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>