@@ -217,9 +217,7 @@ func testCancel(t *testing.T, ignore bool) {
217217 // Either way, this should undo both calls to Notify above.
218218 if ignore {
219219 Ignore (syscall .SIGWINCH , syscall .SIGHUP )
220- // Don't bother deferring a call to Reset: it is documented to undo Notify,
221- // but its documentation says nothing about Ignore, and (as of the time of
222- // writing) it empirically does not undo an Ignore.
220+ defer Reset (syscall .SIGWINCH , syscall .SIGHUP )
223221 } else {
224222 Reset (syscall .SIGWINCH , syscall .SIGHUP )
225223 }
@@ -349,6 +347,8 @@ func TestStop(t *testing.T) {
349347 for _ , sig := range sigs {
350348 sig := sig
351349 t .Run (fmt .Sprint (sig ), func (t * testing.T ) {
350+ defer Reset (sig )
351+
352352 // When calling Notify with a specific signal,
353353 // independent signals should not interfere with each other,
354354 // and we end up needing to wait for signals to quiesce a lot.
@@ -913,3 +913,114 @@ func TestSignalTrace(t *testing.T) {
913913 close (quit )
914914 <- done
915915}
916+
917+ // #46321 test Reset actually undoes the effect of Ignore.
918+ func TestResetIgnore (t * testing.T ) {
919+ if os .Getenv ("GO_TEST_RESET_IGNORE" ) != "" {
920+ s , err := strconv .Atoi (os .Getenv ("GO_TEST_RESET_IGNORE" ))
921+ if err != nil {
922+ t .Fatalf ("failed to parse signal: %v" , err )
923+ }
924+ resetIgnoreTestProgram (syscall .Signal (s ))
925+ }
926+
927+ sigs := []syscall.Signal {
928+ syscall .SIGHUP ,
929+ syscall .SIGINT ,
930+ syscall .SIGUSR1 ,
931+ syscall .SIGTERM ,
932+ syscall .SIGCHLD ,
933+ syscall .SIGWINCH ,
934+ }
935+
936+ for _ , notify := range []bool {false , true } {
937+ for _ , sig := range sigs {
938+ t .Run (fmt .Sprintf ("%s[notify=%t]" , sig , notify ), func (t * testing.T ) {
939+ if Ignored (sig ) {
940+ t .Fatalf ("expected %q to not be ignored initially" , sig )
941+ }
942+
943+ Ignore (sig )
944+ if notify {
945+ c := make (chan os.Signal , 1 )
946+ Notify (c , sig )
947+ defer Stop (c )
948+ }
949+ Reset (sig )
950+
951+ if Ignored (sig ) {
952+ t .Fatalf ("expected %q to not be ignored" , sig )
953+ }
954+
955+ // Child processes inherit the ignored status of signals, so verify that it
956+ // is indeed not ignored.
957+ cmd := testenv .Command (t , testenv .Executable (t ), "-test.run=^TestResetIgnore$" )
958+ cmd .Env = append (os .Environ (), "GO_TEST_RESET_IGNORE=" + strconv .Itoa (int (sig )))
959+ err := cmd .Run ()
960+ if _ , ok := err .(* exec.ExitError ); ok {
961+ t .Fatalf ("expected %q to not be ignored in child process" , sig )
962+ } else if err != nil {
963+ t .Fatalf ("child process failed to launch: %v" , err )
964+ }
965+ })
966+ }
967+ }
968+ }
969+
970+ func resetIgnoreTestProgram (sig os.Signal ) {
971+ if Ignored (sig ) {
972+ os .Exit (1 )
973+ }
974+ os .Exit (0 )
975+ }
976+
977+ // #46321 test Reset correctly undoes the effect of Ignore when the child
978+ // process is started with a signal ignored.
979+ func TestInitiallyIgnoredResetIgnore (t * testing.T ) {
980+ testenv .MustHaveExec (t )
981+
982+ if os .Getenv ("GO_TEST_INITIALLY_IGNORED_RESET_IGNORE" ) != "" {
983+ s , err := strconv .Atoi (os .Getenv ("GO_TEST_INITIALLY_IGNORED_RESET_IGNORE" ))
984+ if err != nil {
985+ t .Fatalf ("failed to parse signal: %v" , err )
986+ }
987+ initiallyIgnoredResetIgnoreTestProgram (syscall .Signal (s ))
988+ }
989+
990+ sigs := []syscall.Signal {
991+ syscall .SIGINT ,
992+ syscall .SIGHUP ,
993+ }
994+
995+ for _ , sig := range sigs {
996+ t .Run (fmt .Sprint (sig ), func (t * testing.T ) {
997+ Ignore (sig )
998+ defer Reset (sig )
999+
1000+ cmd := testenv .Command (t , testenv .Executable (t ), "-test.run=^TestInitiallyIgnoredResetIgnore$" )
1001+ cmd .Env = append (os .Environ (), "GO_TEST_INITIALLY_IGNORED_RESET_IGNORE=" + strconv .Itoa (int (sig )))
1002+ err := cmd .Run ()
1003+ if _ , ok := err .(* exec.ExitError ); ok {
1004+ t .Fatalf ("expected %q to be ignored in child process" , sig )
1005+ } else if err != nil {
1006+ t .Fatalf ("child process failed to launch: %v" , err )
1007+ }
1008+ })
1009+ }
1010+ }
1011+
1012+ func initiallyIgnoredResetIgnoreTestProgram (sig os.Signal ) {
1013+ if ! Ignored (sig ) {
1014+ os .Exit (1 )
1015+ }
1016+ Reset (sig )
1017+ if ! Ignored (sig ) {
1018+ os .Exit (1 )
1019+ }
1020+ Ignore (sig )
1021+ Reset (sig )
1022+ if ! Ignored (sig ) {
1023+ os .Exit (1 )
1024+ }
1025+ os .Exit (0 )
1026+ }
0 commit comments