os: add `signal_opt` and deprecate `signal` (#10005)

pull/10022/head
Enzo 2021-05-05 14:39:02 +02:00 committed by GitHub
parent 8b50a5a171
commit 4ac751d773
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 93 additions and 10 deletions

View File

@ -132,8 +132,6 @@ fn C.sigemptyset() int
fn C.getcwd(buf &char, size size_t) &char fn C.getcwd(buf &char, size size_t) &char
fn C.signal(signal int, handlercb voidptr) voidptr
[trusted] [trusted]
fn C.mktime() int fn C.mktime() int

View File

@ -828,12 +828,6 @@ fn normalize_drive_letter(path string) string {
return path return path
} }
// signal will assign `handler` callback to be called when `signum` signal is received.
pub fn signal(signum int, handler voidptr) voidptr {
res := unsafe { C.signal(signum, handler) }
return res
}
// fork will fork the current system process and return the pid of the fork. // fork will fork the current system process and return the pid of the fork.
pub fn fork() int { pub fn fork() int {
mut pid := -1 mut pid := -1

58
vlib/os/signal.c.v 100644
View File

@ -0,0 +1,58 @@
module os
#include <signal.h>
pub enum Signal {
hup = 1
int
quit
ill
trap
abrt
bus
fpe
kill
usr1
segv
usr2
pipe
alrm
term
stkflt
chld
cont
stop
tstp
ttin
ttou
urg
xcpu
xfsz
vtalrm
prof
winch
poll
pwr
sys
}
type SignalHandler = fn (Signal)
fn C.signal(signal int, handlercb SignalHandler) voidptr
[deprecated: 'use os.signal_opt() instead']
[deprecated_after: '2021-05-18']
pub fn signal(signum int, handler voidptr) voidptr {
return voidptr(signal_opt(Signal(signum), handler) or { C.SIG_ERR })
}
// signal will assign `handler` callback to be called when `signum` signal is received.
pub fn signal_opt(signum Signal, handler SignalHandler) ?SignalHandler {
C.errno = 0
prev_handler := C.signal(int(signum), handler)
if prev_handler == C.SIG_ERR {
// errno isn't correctly set on Windows, but EINVAL is this only possible value it can take anyway
return error_with_code(posix_get_error_msg(C.EINVAL), C.EINVAL)
}
return SignalHandler(prev_handler)
}

View File

@ -0,0 +1,35 @@
import os
fn former_handler(signal os.Signal) {
println('former_handler')
exit(0)
}
fn default_handler(signal os.Signal) {
println('default_handler')
exit(0)
}
fn test_signal_opt() {
os.signal_opt(.int, default_handler) or { assert false }
}
fn test_signal_opt_invalid_argument() {
// Can't register a signal on SIGKILL
if _ := os.signal_opt(.kill, default_handler) {
assert false
}
os.signal_opt(.kill, default_handler) or {
assert err.msg == 'Invalid argument'
assert err.code == 22
}
}
fn test_signal_opt_return_former_handler() {
func1 := os.signal_opt(.term, former_handler) or { panic('unexpected error') }
assert isnil(func1)
func2 := os.signal_opt(.term, default_handler) or { panic('unexpected error') }
assert !isnil(func2)
// this should work, but makes the CI fail because of a bug in clang -fsanitize=memory
// assert func2 == former_handler
}

View File

@ -515,8 +515,6 @@ typedef int (*qsort_callback_func)(const void*, const void*);
#endif #endif
#endif #endif
//#include "fns.h"
#include <signal.h>
#include <stdarg.h> // for va_list #include <stdarg.h> // for va_list
//================================== GLOBALS =================================*/ //================================== GLOBALS =================================*/