Skip to content

Commit e0a04a9

Browse files
authored
Merge pull request #1423 from trungutt/detect-parent-death
Detect parent process death via stdin EOF
2 parents 8526bbb + 2816958 commit e0a04a9

1 file changed

Lines changed: 37 additions & 0 deletions

File tree

cmd/root/api.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package root
22

33
import (
4+
"context"
45
"fmt"
56
"log/slog"
67
"os"
@@ -50,16 +51,52 @@ func newAPICmd() *cobra.Command {
5051
return cmd
5152
}
5253

54+
// monitorStdin monitors stdin for EOF, which indicates the parent process has died.
55+
// When spawned with piped stdio, stdin closes when the parent process dies.
56+
func monitorStdin(ctx context.Context, cancel context.CancelFunc, stdin *os.File) {
57+
// Close stdin when context is cancelled to unblock the read
58+
go func() {
59+
<-ctx.Done()
60+
stdin.Close()
61+
}()
62+
63+
buf := make([]byte, 1)
64+
for {
65+
n, err := stdin.Read(buf)
66+
if err != nil || n == 0 {
67+
// Only log and cancel if context isn't already done (parent died)
68+
if ctx.Err() == nil {
69+
slog.Info("stdin closed, parent process likely died, shutting down")
70+
cancel()
71+
}
72+
return
73+
}
74+
}
75+
}
76+
5377
func (f *apiFlags) runAPICommand(cmd *cobra.Command, args []string) error {
5478
telemetry.TrackCommand("api", args)
5579

5680
ctx := cmd.Context()
81+
82+
// Save stdin before clearing it, so we can monitor for parent death
83+
stdin := os.Stdin
84+
5785
out := cli.NewPrinter(cmd.OutOrStdout())
5886
agentsPath := args[0]
5987

6088
// Make sure no question is ever asked to the user in api mode.
6189
os.Stdin = nil
6290

91+
// Monitor stdin for EOF to detect parent process death.
92+
// When spawned with piped stdio, stdin closes when the parent process dies.
93+
if stdin != nil {
94+
var cancel context.CancelFunc
95+
ctx, cancel = context.WithCancel(ctx)
96+
defer cancel()
97+
go monitorStdin(ctx, cancel, stdin)
98+
}
99+
63100
// Start fake proxy if --fake is specified
64101
cleanup, err := setupFakeProxy(f.fakeResponses, &f.runConfig)
65102
if err != nil {

0 commit comments

Comments
 (0)