48e316b |
Jamozed |
2022-03-01 03:04:16 |
0
|
// timeout.c |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
1
|
// OMKOV coreutils timeout |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
2
|
// Copyright (C) 2022, Jakob Wakeling |
e2140ec |
Jamozed |
2022-03-06 15:27:45 |
3
|
// MIT Licence |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
4
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
5
|
#define VERSION "0.1.0" |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
6
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
7
|
#include "util/error.h" |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
8
|
#include "util/optget.h" |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
9
|
#include "util/util.h" |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
10
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
11
|
#include <sys/wait.h> |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
12
|
#include <unistd.h> |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
13
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
14
|
#include <errno.h> |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
15
|
#include <signal.h> |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
16
|
#include <stdio.h> |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
17
|
#include <stdlib.h> |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
18
|
#include <time.h> |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
19
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
20
|
static struct lop lops[] = { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
21
|
{ "help", ARG_NUL, 256 }, |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
22
|
{ "version", ARG_NUL, 257 }, |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
23
|
{ NULL, 0, 0 } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
24
|
}; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
25
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
26
|
static f64 itime = 0, ktime = 0; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
27
|
static int tosig = SIGTERM; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
28
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
29
|
static pid_t pid = 0; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
30
|
static bool tout = false; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
31
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
32
|
static f64 time_parse(const char *s); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
33
|
static int timeout(char *av[]); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
34
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
35
|
static void signal_install(int sig); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
36
|
static void signal_block(int sig, sigset_t *oset); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
37
|
static void handle_sigalrm(int sig); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
38
|
static void handle_sigchld(int sig); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
39
|
static int signal_send(pid_t pid, int sig); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
40
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
41
|
static void timer(f64 duration); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
42
|
static struct timespec f64totimespec(f64 seconds); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
43
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
44
|
static void hlp(void); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
45
|
static void ver(void); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
46
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
47
|
int main(int ac, char *av[]) { A0 = av[0]; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
48
|
struct opt opt = OPTGET_INIT; opt.str = "k:s:"; opt.lops = lops; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
49
|
for (int o; (o = optget(&opt, av, 1)) != -1;) switch (o) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
50
|
case 'k': { ktime = time_parse(opt.arg); } break; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
51
|
case 's': { /* TODO */ return 1; } break; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
52
|
case 256: { hlp(); } return 0; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
53
|
case 257: { ver(); } return 0; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
54
|
default: {} return 125; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
55
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
56
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
57
|
if ((ac - opt.ind) < 2) { error(125, "missing operand(s)"); } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
58
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
59
|
itime = time_parse(av[opt.ind]); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
60
|
return timeout(&av[opt.ind + 1]); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
61
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
62
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
63
|
/* Parse a duration string. */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
64
|
static inline f64 time_parse(const char *s) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
65
|
char *ep = NULL; errno = 0; f64 time = strtod(s, &ep); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
66
|
if (errno != 0) { error(1, "%s: %s", s, SERR); } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
67
|
if (time < 0) { error(1, "%s: duration cannot be negative", s); } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
68
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
69
|
/* Check for an apply any valid suffix */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
70
|
if (ep != NULL && ep[0] != '\0') { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
71
|
switch (ep[0]) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
72
|
case 'D': { time *= 86400; } break; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
73
|
case 'h': { time *= 3600; } break; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
74
|
case 'm': { time *= 60; } break; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
75
|
case 's': { time *= 1; } break; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
76
|
default: { error(1, "%s: invalid suffix", s); } break; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
77
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
78
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
79
|
if (ep[1] != '\0') { error(1, "%s: invalid suffix", s); } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
80
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
81
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
82
|
return time; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
83
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
84
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
85
|
static int timeout(char *av[]) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
86
|
signal_install(tosig); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
87
|
signal(SIGTTIN, SIG_IGN); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
88
|
signal(SIGTTOU, SIG_IGN); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
89
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
90
|
switch ((pid = fork())) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
91
|
case -1: { error(125, "%s", SERR); } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
92
|
case 0: { /* Child */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
93
|
signal(SIGTTIN, SIG_DFL); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
94
|
signal(SIGTTOU, SIG_DFL); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
95
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
96
|
execvp(av[0], av); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
97
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
98
|
error((errno = ENOENT) ? 127 : 126, "%s: %s", av[0], SERR); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
99
|
} break; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
100
|
default: { /* Parent */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
101
|
int status; pid_t wpid; sigset_t sset; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
102
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
103
|
/* Unblock and start the timeout timer */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
104
|
/* TODO unblock */ timer(itime); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
105
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
106
|
signal_block(tosig, &sset); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
107
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
108
|
/* Wait for the timer to expire, or the child to die */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
109
|
for (; (wpid = waitpid(pid, &status, WNOHANG)) == 0;) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
110
|
sigsuspend(&sset); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
111
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
112
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
113
|
if (wpid == -1) { error(125, "%s", SERR); } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
114
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
115
|
/* If the child process exited normally */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
116
|
if (WIFEXITED(status)) { status = WEXITSTATUS(status); } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
117
|
/* If the child process exited abnormally */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
118
|
else if (WIFSIGNALED(status)) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
119
|
int sig = WTERMSIG(status); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
120
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
121
|
status = 128 + sig; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
122
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
123
|
else { error(125, "%s", SERR); } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
124
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
125
|
return tout ? 124 : status; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
126
|
} break; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
127
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
128
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
129
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
130
|
/* Configure SIGALRM handling. */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
131
|
static void signal_install(int sig) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
132
|
struct sigaction sa0 = { .sa_handler = handle_sigalrm, .sa_flags = SA_RESTART }; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
133
|
struct sigaction sa1 = { .sa_handler = handle_sigchld, .sa_flags = SA_RESTART }; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
134
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
135
|
sigemptyset(&sa0.sa_mask); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
136
|
sigaction(SIGALRM, &sa0, NULL); /* Alarm signal, from the timeout timer */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
137
|
sigaction(SIGHUP, &sa0, NULL); /* Hangup signal, i.e. upon tty closing */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
138
|
sigaction(SIGINT, &sa0, NULL); /* Interrupt signal, i.e. from Ctrl+C */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
139
|
sigaction(SIGQUIT, &sa0, NULL); /* Quit signal, i.e. from Ctrl+\ */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
140
|
sigaction(SIGTERM, &sa0, NULL); /* Terminate signal, i.e. upon death */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
141
|
sigaction(sig, &sa0, NULL); /* User specified signal */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
142
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
143
|
sigemptyset(&sa1.sa_mask); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
144
|
sigaction(SIGCHLD, &sa1, NULL); /* Child signal, i.e. upon child death */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
145
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
146
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
147
|
/* Block all appropriate signals, as per signal_install(). */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
148
|
static void signal_block(int sig, sigset_t *oset) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
149
|
sigset_t set; sigemptyset(&set); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
150
|
sigaddset(&set, SIGALRM); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
151
|
sigaddset(&set, SIGHUP); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
152
|
sigaddset(&set, SIGINT); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
153
|
sigaddset(&set, SIGQUIT); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
154
|
sigaddset(&set, SIGTERM); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
155
|
sigaddset(&set, sig); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
156
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
157
|
sigaddset(&set, SIGCHLD); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
158
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
159
|
if (sigprocmask(SIG_BLOCK, &set, oset) == -1) { warn("%s", SERR); } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
160
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
161
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
162
|
/* Handle SIGALRM. */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
163
|
static void handle_sigalrm(int sig) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
164
|
if (sig == SIGALRM) { tout = true; sig = tosig; } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
165
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
166
|
/* If we are the child, or the child is not yet born, then exit */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
167
|
if (pid == 0) { exit(128 + sig); } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
168
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
169
|
if (ktime) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
170
|
/* Start a new timeout, after which SIGKILL will be sent */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
171
|
int ern = errno; tosig = SIGKILL; timer(ktime); ktime = 0; errno = ern; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
172
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
173
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
174
|
signal_send(pid, sig); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
175
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
176
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
177
|
/* Handle SIGCHLD. */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
178
|
static void handle_sigchld(int sig) {} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
179
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
180
|
/* Send a signal to a process, ignoring signals in the case of a group. */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
181
|
static int signal_send(pid_t pid, int sig) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
182
|
if (pid == 0) { signal(sig, SIG_IGN); } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
183
|
return kill(pid, sig); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
184
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
185
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
186
|
/* Start the timeout timer, after which we'll recieve a SIGALRM. */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
187
|
static void timer(f64 duration) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
188
|
struct timespec ts = f64totimespec(duration); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
189
|
struct itimerspec its = { { 0, 0 }, ts }; timer_t tid; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
190
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
191
|
/* Create and set a timer with timer_create and timer_settime */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
192
|
if (timer_create(CLOCK_REALTIME, NULL, &tid) == 0) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
193
|
if (timer_settime(tid, 0, &its, NULL) == 0) { return; } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
194
|
else { warn("timer_settime: %s", SERR); timer_delete(tid); } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
195
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
196
|
else { warn("timer_create: %s", SERR); } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
197
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
198
|
/* Fallback to alarm() with single second precision upon failure */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
199
|
if (duration >= (f64)U32_MAX) { alarm(U32_MAX); } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
200
|
else { alarm((u32)duration + ((u32)duration < duration)); } |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
201
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
202
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
203
|
/* Convert an f64 value to a timespec struct. */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
204
|
static struct timespec f64totimespec(f64 seconds) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
205
|
struct timespec ts; seconds += 0.5e-9; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
206
|
ts.tv_sec = (time_t)seconds; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
207
|
ts.tv_nsec = (seconds - ts.tv_sec) * 1.0e+9; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
208
|
return ts; |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
209
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
210
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
211
|
/* Print help information. */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
212
|
static void hlp(void) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
213
|
puts("timeout - Invoke a command with a timelimit\n"); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
214
|
puts("Usage:"); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
215
|
puts(" timeout [-ks] duration command [argument...]\n"); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
216
|
puts("Options:"); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
217
|
puts(" -k duration Send a KILL signal after the specified duration"); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
218
|
puts(" -s signal Send the specified signal instead of SIGINT"); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
219
|
puts(" --help Display help information"); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
220
|
puts(" --version Display version information"); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
221
|
} |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
222
|
|
48e316b |
Jamozed |
2022-03-01 03:04:16 |
223
|
/* Print version information. */ |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
224
|
static void ver(void) { |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
225
|
puts("OMKOV cryptutils timeout, version " VERSION); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
226
|
puts("Copyright (C) 2022, Jakob Wakeling"); |
e2140ec |
Jamozed |
2022-03-06 15:27:45 |
227
|
puts("MIT Licence (https://opensource.org/licenses/MIT)"); |
48e316b |
Jamozed |
2022-03-01 03:04:16 |
228
|
} |
|
|
|
229
|
|