@@ -859,34 +859,85 @@ test "shutdown socket" {
859
859
std .net .Stream .close (.{ .handle = sock });
860
860
}
861
861
862
- test "sigaction" {
862
+ test "sigset empty/full" {
863
+ if (native_os == .wasi or native_os == .windows )
864
+ return error .SkipZigTest ;
865
+
866
+ var set : posix.sigset_t = undefined ;
867
+
868
+ posix .sigemptyset (& set );
869
+ for (1.. posix .NSIG ) | i | {
870
+ try expectEqual (false , posix .sigismember (& set , @truncate (i )));
871
+ }
872
+
873
+ // The C library can reserve some (unnamed) signals, so can't check the full
874
+ // NSIG set is defined, but just test a couple:
875
+ posix .sigfillset (& set );
876
+ try expectEqual (true , posix .sigismember (& set , @truncate (posix .SIG .USR1 )));
877
+ try expectEqual (true , posix .sigismember (& set , @truncate (posix .SIG .INT )));
878
+ }
879
+
880
+ // Some signals (32 - 34 on glibc/musl) are not allowed to be added to a
881
+ // sigset by the C library, so avoid testing them.
882
+ fn reserved_signo (i : usize ) bool {
883
+ return builtin .link_libc and (i >= 32 and i <= 34 );
884
+ }
885
+
886
+ test "sigset add/del" {
863
887
if (native_os == .wasi or native_os == .windows )
864
888
return error .SkipZigTest ;
865
889
866
- // https://github.com/ziglang/zig/issues/7427
867
- if (native_os == .linux and builtin .target .cpu .arch == .x86 )
890
+ var sigset = posix .empty_sigset ;
891
+
892
+ // See that none are set, then set each one, see that they're all set, then
893
+ // remove them all, and then see that none are set.
894
+ for (1.. posix .NSIG ) | i | {
895
+ try expectEqual (false , posix .sigismember (& sigset , @truncate (i )));
896
+ }
897
+ for (1.. posix .NSIG ) | i | {
898
+ if (! reserved_signo (i )) {
899
+ posix .sigaddset (& sigset , @truncate (i ));
900
+ }
901
+ }
902
+ for (1.. posix .NSIG ) | i | {
903
+ if (! reserved_signo (i )) {
904
+ try expectEqual (true , posix .sigismember (& sigset , @truncate (i )));
905
+ }
906
+ try expectEqual (false , posix .sigismember (& posix .empty_sigset , @truncate (i )));
907
+ }
908
+ for (1.. posix .NSIG ) | i | {
909
+ if (! reserved_signo (i )) {
910
+ posix .sigdelset (& sigset , @truncate (i ));
911
+ }
912
+ }
913
+ for (1.. posix .NSIG ) | i | {
914
+ try expectEqual (false , posix .sigismember (& sigset , @truncate (i )));
915
+ }
916
+ }
917
+
918
+ test "sigaction" {
919
+ if (native_os == .wasi or native_os == .windows )
868
920
return error .SkipZigTest ;
869
921
870
922
// https://github.com/ziglang/zig/issues/15381
871
923
if (native_os == .macos and builtin .target .cpu .arch == .x86_64 ) {
872
924
return error .SkipZigTest ;
873
925
}
874
926
927
+ const test_signo = posix .SIG .USR1 ;
928
+
875
929
const S = struct {
876
930
var handler_called_count : u32 = 0 ;
877
931
878
932
fn handler (sig : i32 , info : * const posix.siginfo_t , ctx_ptr : ? * anyopaque ) callconv (.c ) void {
879
933
_ = ctx_ptr ;
880
934
// Check that we received the correct signal.
881
- switch (native_os ) {
882
- .netbsd = > {
883
- if (sig == posix .SIG .USR1 and sig == info .info .signo )
884
- handler_called_count += 1 ;
885
- },
886
- else = > {
887
- if (sig == posix .SIG .USR1 and sig == info .signo )
888
- handler_called_count += 1 ;
889
- },
935
+ const info_sig = switch (native_os ) {
936
+ .netbsd = > info .info .signo ,
937
+ else = > info .signo ,
938
+ };
939
+ if (sig == test_signo and sig == info_sig ) {
940
+ handler_called_count += 1 ;
890
941
}
891
942
}
892
943
};
@@ -899,39 +950,93 @@ test "sigaction" {
899
950
var old_sa : posix.Sigaction = undefined ;
900
951
901
952
// Install the new signal handler.
902
- posix .sigaction (posix . SIG . USR1 , & sa , null );
953
+ posix .sigaction (test_signo , & sa , null );
903
954
904
955
// Check that we can read it back correctly.
905
- posix .sigaction (posix . SIG . USR1 , null , & old_sa );
956
+ posix .sigaction (test_signo , null , & old_sa );
906
957
try testing .expectEqual (& S .handler , old_sa .handler .sigaction .? );
907
958
try testing .expect ((old_sa .flags & posix .SA .SIGINFO ) != 0 );
908
959
909
960
// Invoke the handler.
910
- try posix .raise (posix . SIG . USR1 );
911
- try testing .expect ( S .handler_called_count == 1 );
961
+ try posix .raise (test_signo );
962
+ try testing .expectEqual ( 1 , S .handler_called_count );
912
963
913
964
// Check if passing RESETHAND correctly reset the handler to SIG_DFL
914
- posix .sigaction (posix . SIG . USR1 , null , & old_sa );
965
+ posix .sigaction (test_signo , null , & old_sa );
915
966
try testing .expectEqual (posix .SIG .DFL , old_sa .handler .handler );
916
967
917
968
// Reinstall the signal w/o RESETHAND and re-raise
918
969
sa .flags = posix .SA .SIGINFO ;
919
- posix .sigaction (posix . SIG . USR1 , & sa , null );
920
- try posix .raise (posix . SIG . USR1 );
921
- try testing .expect ( S .handler_called_count == 2 );
970
+ posix .sigaction (test_signo , & sa , null );
971
+ try posix .raise (test_signo );
972
+ try testing .expectEqual ( 2 , S .handler_called_count );
922
973
923
974
// Now set the signal to ignored
924
975
sa .handler = .{ .handler = posix .SIG .IGN };
925
976
sa .flags = 0 ;
926
- posix .sigaction (posix . SIG . USR1 , & sa , null );
977
+ posix .sigaction (test_signo , & sa , null );
927
978
928
979
// Re-raise to ensure handler is actually ignored
929
- try posix .raise (posix . SIG . USR1 );
930
- try testing .expect ( S .handler_called_count == 2 );
980
+ try posix .raise (test_signo );
981
+ try testing .expectEqual ( 2 , S .handler_called_count );
931
982
932
983
// Ensure that ignored state is returned when querying
933
- posix .sigaction (posix .SIG .USR1 , null , & old_sa );
934
- try testing .expectEqual (posix .SIG .IGN , old_sa .handler .handler .? );
984
+ posix .sigaction (test_signo , null , & old_sa );
985
+ try testing .expectEqual (posix .SIG .IGN , old_sa .handler .handler );
986
+ }
987
+
988
+ test "sigset_t bits" {
989
+ if (native_os == .wasi or native_os == .windows )
990
+ return error .SkipZigTest ;
991
+
992
+ const S = struct {
993
+ var expected_sig : i32 = undefined ;
994
+ var handler_called_count : u32 = 0 ;
995
+
996
+ fn handler (sig : i32 , info : * const posix.siginfo_t , ctx_ptr : ? * anyopaque ) callconv (.c ) void {
997
+ _ = ctx_ptr ;
998
+
999
+ const info_sig = switch (native_os ) {
1000
+ .netbsd = > info .info .signo ,
1001
+ else = > info .signo ,
1002
+ };
1003
+ if (sig == expected_sig and sig == info_sig ) {
1004
+ handler_called_count += 1 ;
1005
+ }
1006
+ }
1007
+ };
1008
+
1009
+ // To check that sigset_t mapping matches kernel (think u32/u64
1010
+ // mismatches on big-endian), try sending a blocked signal to make
1011
+ // sure the mask matches the signal.
1012
+ inline for ([_ ]usize { posix .SIG .INT , posix .SIG .USR1 , 62 , 94 , 126 }) | test_signo | {
1013
+ if (test_signo >= posix .NSIG ) continue ;
1014
+
1015
+ S .expected_sig = test_signo ;
1016
+ S .handler_called_count = 0 ;
1017
+
1018
+ var sa : posix.Sigaction = .{
1019
+ .handler = .{ .sigaction = & S .handler },
1020
+ .mask = posix .empty_sigset ,
1021
+ .flags = posix .SA .SIGINFO | posix .SA .RESETHAND ,
1022
+ };
1023
+ var old_sa : posix.Sigaction = undefined ;
1024
+
1025
+ // Install the new signal handler.
1026
+ posix .sigaction (test_signo , & sa , & old_sa );
1027
+
1028
+ // block the signal and see that its delayed until unblocked
1029
+ var block_one = posix .empty_sigset ;
1030
+ _ = posix .sigaddset (& block_one , test_signo );
1031
+ posix .sigprocmask (posix .SIG .BLOCK , & block_one , null );
1032
+ try posix .raise (test_signo );
1033
+ try testing .expectEqual (0 , S .handler_called_count );
1034
+ posix .sigprocmask (posix .SIG .UNBLOCK , & block_one , null );
1035
+ try testing .expectEqual (1 , S .handler_called_count );
1036
+
1037
+ // Restore original handler
1038
+ posix .sigaction (test_signo , & old_sa , null );
1039
+ }
935
1040
}
936
1041
937
1042
test "dup & dup2" {
0 commit comments