signal.ha (3964B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 // TODO: work when _NSIG != 32 5 6 export fn alarm(sec: uint) uint = { 7 let nval = itimerval { ... }; 8 let oval = itimerval { ... }; 9 nval.it_value.tv_sec = sec: time_t; 10 setitimer(ITIMER_REAL, &nval, &oval)!; 11 if (oval.it_value.tv_usec != 0) { 12 oval.it_value.tv_sec += 1; 13 }; 14 return oval.it_value.tv_sec: uint; 15 }; 16 17 export def ITIMER_REAL: int = 0; 18 export def ITIMER_VIRTUAL: int = 1; 19 export def ITIMER_PROF: int = 2; 20 21 export type itimerval = struct { 22 it_interval: timeval, 23 it_value: timeval, 24 }; 25 26 export fn getitimer( 27 which: int, 28 cur: *itimerval, 29 ) (void | errno) = { 30 wrap_return(syscall2(SYS_compat_50_getitimer, which: u64, cur: uintptr: u64))?; 31 }; 32 33 export fn setitimer( 34 which: int, 35 newval: *itimerval, 36 oldval: nullable *itimerval, 37 ) (void | errno) = { 38 wrap_return(syscall3(SYS_compat_50_setitimer, 39 which: u64, 40 newval: uintptr: u64, 41 oldval: uintptr: u64))?; 42 }; 43 44 export fn sigtimedwait( 45 set: *sigset, 46 info: nullable *siginfo, 47 timeout: nullable *timespec, 48 ) (int | errno) = { 49 return wrap_return(syscall3(SYS_compat_50___sigtimedwait, 50 set: uintptr: u64, 51 info: uintptr: u64, 52 timeout: uintptr: u64, 53 ))?: int; 54 }; 55 56 export fn sigwait(set: *sigset, sig: *int) (void | errno) = { 57 *sig = sigtimedwait(set, null, null)?; 58 }; 59 60 export fn sigwaitinfo(set: *sigset, info: nullable *siginfo) (void | errno) = { 61 sigtimedwait(set, info, null)?; 62 }; 63 64 export fn sigemptyset(set: *sigset) void = { 65 for (let i = 0z; i < len(set.__bits); i += 1) { 66 set.__bits[i] = 0; 67 }; 68 }; 69 70 export fn sigaddset(set: *sigset, signum: int) (void | errno) = { 71 if (signum < 1 || signum > NSIG) { 72 return EINVAL; 73 }; 74 signum -= 1; 75 set.__bits[signum >> 5] |= (1 << signum): u32; 76 }; 77 78 export fn sigdelset(set: *sigset, signum: int) (void | errno) = { 79 if (signum < 1 || signum > NSIG) { 80 return EINVAL; 81 }; 82 signum -= 1; 83 set.__bits[signum >> 5] &= ~(1 << signum: u32); 84 }; 85 86 export fn sigismember(set: *sigset, signum: int) (bool | errno) = { 87 if (signum < 1 || signum > NSIG) { 88 return EINVAL; 89 }; 90 signum -= 1; 91 return (set.__bits[signum >> 5] & (1 << signum: u32)) != 0; 92 }; 93 94 export fn sigfillset(set: *sigset) (void | errno) = { 95 for (let i = 0z; i < len(set.__bits); i += 1) { 96 set.__bits[i] = ~0u32; 97 }; 98 }; 99 100 // Test sigset operations do not fail for valid signal numbers. 101 @test fn sigset_valid_signum() void = { 102 let set: sigset = sigset { ... }; 103 sigemptyset(&set); 104 105 assert(!(sigismember(&set, 1) is errno), "Unexpected error"); 106 assert(!(sigismember(&set, 15) is errno), "Unexpected error"); 107 assert(!(sigismember(&set, NSIG) is errno), "Unexpected error"); 108 109 assert(!(sigaddset(&set, 1) is errno), "Unexpected error"); 110 assert(!(sigaddset(&set, 15) is errno), "Unexpected error"); 111 assert(!(sigaddset(&set, NSIG) is errno), "Unexpected error"); 112 113 // It's ok to add a signal that is already present in the set. 114 assert(!(sigaddset(&set, 1) is errno), "Unexpected error"); 115 116 assert(!(sigdelset(&set, 1) is errno), "Unexpected error"); 117 assert(!(sigdelset(&set, 15) is errno), "Unexpected error"); 118 assert(!(sigdelset(&set, NSIG) is errno), "Unexpected error"); 119 120 // It's ok to delete a signal that is not present in the set. 121 assert(!(sigdelset(&set, 10) is errno), "Unexpected error"); 122 }; 123 124 // Test sigset operations fail for invalid signal numbers. 125 @test fn sigset_invalid_signum() void = { 126 let set: sigset = sigset { ... }; 127 sigemptyset(&set); 128 129 assert(sigismember(&set, -1) is errno, "Expected error"); 130 assert(sigismember(&set, 0) is errno, "Expected error"); 131 assert(sigismember(&set, NSIG + 1) is errno, "Expected error"); 132 133 assert(sigaddset(&set, -1) is errno, "Expected error"); 134 assert(sigaddset(&set, 0) is errno, "Expected error"); 135 assert(sigaddset(&set, NSIG + 1) is errno, "Expected error"); 136 137 assert(sigdelset(&set, -1) is errno, "Expected error"); 138 assert(sigdelset(&set, 0) is errno, "Expected error"); 139 assert(sigdelset(&set, NSIG + 1) is errno, "Expected error"); 140 };