1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
// This file is part of yash, an extended POSIX shell.
// Copyright (C) 2024 WATANABE Yuki
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//! Kill built-in
//!
//! The **`kill`** built-in sends a signal to processes.
//!
//! # Synopsis
//!
//! ```sh
//! kill [-s SIGNAL|-n SIGNAL|-SIGNAL] target…
//! ```
//!
//! ```sh
//! kill -l|-v [SIGNAL|exit_status]…
//! ```
//!
//! # Description
//!
//! Without the `-l` or `-v` option, the built-in sends a signal to processes.
//!
//! With the `-l` or `-v` option, the built-in lists signal names or
//! descriptions.
//!
//! # Options
//!
//! The **`-s`** or **`-n`** option specifies the signal to send. The signal
//! name is case-insensitive, but must be specified without the `SIG` prefix.
//! The default signal is `SIGTERM`. (TODO: Allow the `SIG` prefix)
//!
//! The signal may be specified as a number instead of a name. If the number
//! is zero, the built-in does not send a signal, but instead checks whether
//! the shell can send the signal to the target processes.
//!
//! The obsolete syntax allows the signal name or number to be specified
//! directly after the hyphen like `-TERM` and `-15` instead of `-s TERM` and
//! `-n 15`.
//!
//! The **`-l`** option lists signal names. The names are printed one per line,
//! without the `SIG` prefix.
//!
//! The **`-v`** option lists signal descriptions. This works like the `-l`
//! option, but prints the signal number, name, and description instead of
//! just the name. The `-v` option may be used with the `-l` option, in which
//! case the `-l` option is ignored. (TODO: The description is not yet printed)
//!
//! # Operands
//!
//! Without the `-l` or `-v` option, the built-in takes one or more operands
//! that specify the target processes. Each operand is one of the following:
//!
//! - A positive decimal integer, which should be a process ID
//! - A negative decimal integer, which should be a negated process group ID
//! - `0`, which means the current process group
//! - `-1`, which means all processes
//! - A [job ID](yash_env::job::id) with a leading `%`
//!
//! With the `-l` or `-v` option, the built-in may take operands that limit the
//! output to the specified signals. Each operand is one of the following:
//!
//! - The exit status of a process that was terminated by a signal
//! - A signal number
//! - A signal name without the `SIG` prefix
//!
//! Without operands, the `-l` and `-v` options list all signals.
//!
//! # Errors
//!
//! It is an error if:
//!
//! - The `-l` or `-v` option is not specified and no target processes are
//! specified.
//! - A specified signal is not supported by the shell.
//! - A specified target process does not exist.
//! - The target job specified by a job ID operand is not [job-controlled] by
//! the shell.
//! - The signal cannot be sent to any of the target processes specified by an
//! operand.
//! - An operand specified with the `-l` or `-v` option does not identify a
//! supported signal.
//!
//! [job-controlled]: yash_env::job::Job::job_controlled
//!
//! # Exit status
//!
//! The exit status is zero unless an error occurs. The exit status is zero if
//! the signal is sent to at least one process for each operand, even if the
//! signal cannot be sent to some of the processes.
//!
//! # Usage notes
//!
//! When a target is specified as a job ID, the built-in cannot tell whether
//! the job process group still exists. If the job process group has been
//! terminated and another process group has been created with the same
//! process group ID, the built-in will send the signal to the new process
//! group.
//!
//! # Portability
//!
//! Specifying a signal number other than `0` to the `-s` option is a
//! non-standard extension.
//!
//! Specifying a signal number to the `-n` option is a ksh extension. This
//! implementation also supports the `-n` option with a signal name.
//!
//! The `kill -SIGNAL target…` form may not be parsed as expected by other
//! implementations when the signal name starts with an `s`. For example, `kill
//! -stop 123` may try to send the `SIGTOP` signal instead of the `SIGSTOP`
//! signal.
//!
//! POSIX defines the following signal numbers:
//!
//! - `0` (a dummy signal that can be used to check whether the shell can send
//! a signal to a process)
//! - `1` (`SIGHUP`)
//! - `2` (`SIGINT`)
//! - `3` (`SIGQUIT`)
//! - `6` (`SIGABRT`)
//! - `9` (`SIGKILL`)
//! - `14` (`SIGALRM`)
//! - `15` (`SIGTERM`)
//!
//! Other signal numbers are implementation-defined.
//!
//! Using the `-l` option with more than one operand is a non-standard
//! extension. Specifying a signal name operand to the `-l` option is a
//! non-standard extension.
//!
//! The `-v` option is a non-standard extension.
//!
//! Some implementations print `0` or `EXIT` for `kill -l 0` or `kill -l EXIT`
//! while this implementation regards them as invalid operands.
//!
//! On some systems, a signal may have more than one name. There seems to be no
//! consensus whether `kill -l` should print all names or just one name for each
//! signal. This implementation currently prints all names, but this behavior
//! may change in the future.
use cratereport_error;
use Field;
use Env;
pub use Signal;
/// Parsed command line arguments
/// Entry point of the kill built-in
pub async