Skip to content

Commit 4ac751d

Browse files
authored
os: add signal_opt and deprecate signal (#10005)
1 parent 8b50a5a commit 4ac751d

File tree

5 files changed

+93
-10
lines changed

5 files changed

+93
-10
lines changed

vlib/builtin/cfns.c.v

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,6 @@ fn C.sigemptyset() int
132132

133133
fn C.getcwd(buf &char, size size_t) &char
134134

135-
fn C.signal(signal int, handlercb voidptr) voidptr
136-
137135
[trusted]
138136
fn C.mktime() int
139137

vlib/os/os_c.v

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -828,12 +828,6 @@ fn normalize_drive_letter(path string) string {
828828
return path
829829
}
830830

831-
// signal will assign `handler` callback to be called when `signum` signal is received.
832-
pub fn signal(signum int, handler voidptr) voidptr {
833-
res := unsafe { C.signal(signum, handler) }
834-
return res
835-
}
836-
837831
// fork will fork the current system process and return the pid of the fork.
838832
pub fn fork() int {
839833
mut pid := -1

vlib/os/signal.c.v

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
module os
2+
3+
#include <signal.h>
4+
5+
pub enum Signal {
6+
hup = 1
7+
int
8+
quit
9+
ill
10+
trap
11+
abrt
12+
bus
13+
fpe
14+
kill
15+
usr1
16+
segv
17+
usr2
18+
pipe
19+
alrm
20+
term
21+
stkflt
22+
chld
23+
cont
24+
stop
25+
tstp
26+
ttin
27+
ttou
28+
urg
29+
xcpu
30+
xfsz
31+
vtalrm
32+
prof
33+
winch
34+
poll
35+
pwr
36+
sys
37+
}
38+
39+
type SignalHandler = fn (Signal)
40+
41+
fn C.signal(signal int, handlercb SignalHandler) voidptr
42+
43+
[deprecated: 'use os.signal_opt() instead']
44+
[deprecated_after: '2021-05-18']
45+
pub fn signal(signum int, handler voidptr) voidptr {
46+
return voidptr(signal_opt(Signal(signum), handler) or { C.SIG_ERR })
47+
}
48+
49+
// signal will assign `handler` callback to be called when `signum` signal is received.
50+
pub fn signal_opt(signum Signal, handler SignalHandler) ?SignalHandler {
51+
C.errno = 0
52+
prev_handler := C.signal(int(signum), handler)
53+
if prev_handler == C.SIG_ERR {
54+
// errno isn't correctly set on Windows, but EINVAL is this only possible value it can take anyway
55+
return error_with_code(posix_get_error_msg(C.EINVAL), C.EINVAL)
56+
}
57+
return SignalHandler(prev_handler)
58+
}

vlib/os/signal_test.v

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import os
2+
3+
fn former_handler(signal os.Signal) {
4+
println('former_handler')
5+
exit(0)
6+
}
7+
8+
fn default_handler(signal os.Signal) {
9+
println('default_handler')
10+
exit(0)
11+
}
12+
13+
fn test_signal_opt() {
14+
os.signal_opt(.int, default_handler) or { assert false }
15+
}
16+
17+
fn test_signal_opt_invalid_argument() {
18+
// Can't register a signal on SIGKILL
19+
if _ := os.signal_opt(.kill, default_handler) {
20+
assert false
21+
}
22+
os.signal_opt(.kill, default_handler) or {
23+
assert err.msg == 'Invalid argument'
24+
assert err.code == 22
25+
}
26+
}
27+
28+
fn test_signal_opt_return_former_handler() {
29+
func1 := os.signal_opt(.term, former_handler) or { panic('unexpected error') }
30+
assert isnil(func1)
31+
func2 := os.signal_opt(.term, default_handler) or { panic('unexpected error') }
32+
assert !isnil(func2)
33+
// this should work, but makes the CI fail because of a bug in clang -fsanitize=memory
34+
// assert func2 == former_handler
35+
}

vlib/v/gen/c/cheaders.v

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,8 +515,6 @@ typedef int (*qsort_callback_func)(const void*, const void*);
515515
#endif
516516
#endif
517517
518-
//#include "fns.h"
519-
#include <signal.h>
520518
#include <stdarg.h> // for va_list
521519
522520
//================================== GLOBALS =================================*/

0 commit comments

Comments
 (0)