@@ -11,19 +11,23 @@ import (
11
11
"internal/testenv"
12
12
"io"
13
13
"os"
14
+ "os/exec"
15
+ "os/signal"
14
16
"os/user"
15
17
"path/filepath"
16
18
"runtime"
17
19
"slices"
18
20
"strconv"
19
21
"strings"
22
+ "sync"
20
23
"syscall"
21
24
"testing"
22
25
"time"
23
26
)
24
27
25
28
func init () {
26
29
registerHelperCommand ("pwd" , cmdPwd )
30
+ registerHelperCommand ("signaltest" , cmdSignalTest )
27
31
}
28
32
29
33
func cmdPwd (... string ) {
@@ -274,3 +278,55 @@ func TestExplicitPWD(t *testing.T) {
274
278
})
275
279
}
276
280
}
281
+
282
+ // Issue 71828.
283
+ func TestSIGCHLD (t * testing.T ) {
284
+ cmd := helperCommand (t , "signaltest" )
285
+ out , err := cmd .CombinedOutput ()
286
+ t .Logf ("%s" , out )
287
+ if err != nil {
288
+ t .Error (err )
289
+ }
290
+ }
291
+
292
+ // cmdSignaltest is for TestSIGCHLD.
293
+ // This runs in a separate process because the bug only happened
294
+ // the first time that a child process was started.
295
+ func cmdSignalTest (... string ) {
296
+ chSig := make (chan os.Signal , 1 )
297
+ signal .Notify (chSig , syscall .SIGCHLD )
298
+
299
+ var wg sync.WaitGroup
300
+ wg .Add (1 )
301
+ go func () {
302
+ defer wg .Done ()
303
+ c := 0
304
+ for range chSig {
305
+ c ++
306
+ fmt .Printf ("SIGCHLD %d\n " , c )
307
+ if c > 1 {
308
+ fmt .Println ("too many SIGCHLD signals" )
309
+ os .Exit (1 )
310
+ }
311
+ }
312
+ }()
313
+ defer func () {
314
+ signal .Reset (syscall .SIGCHLD )
315
+ close (chSig )
316
+ wg .Wait ()
317
+ }()
318
+
319
+ exe , err := os .Executable ()
320
+ if err != nil {
321
+ fmt .Printf ("os.Executable failed: %v\n " , err )
322
+ os .Exit (1 )
323
+ }
324
+
325
+ cmd := exec .Command (exe , "hang" , "200ms" )
326
+ cmd .Stdout = os .Stdout
327
+ cmd .Stderr = os .Stderr
328
+ if err := cmd .Run (); err != nil {
329
+ fmt .Printf ("failed to run child process: %v\n " , err )
330
+ os .Exit (1 )
331
+ }
332
+ }
0 commit comments