Skip to content

Commit 45ccff9

Browse files
committed
fix: avoid readline spin when stdin is not a TTY
When launched headlessly (stdin=/dev/null, e.g. GUI), readline Readline() fails (term.MakeRaw -> ENOTTY). StartContext() retries in a tight loop, causing ~130% CPU.
1 parent 6dc716f commit 45ccff9

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

client/core/console.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,21 @@ import (
55
"errors"
66
"fmt"
77
"io"
8+
"os"
9+
"os/signal"
810
"path/filepath"
911
"strings"
12+
"syscall"
1013
"time"
1114

1215
"github.com/chainreactors/IoM-go/client"
1316
"github.com/chainreactors/IoM-go/consts"
17+
"github.com/chainreactors/logs"
1418
"github.com/chainreactors/malice-network/client/repl"
1519
"github.com/reeflective/console"
1620
"github.com/spf13/cobra"
1721
"golang.org/x/exp/slices"
22+
"golang.org/x/term"
1823
"google.golang.org/grpc/metadata"
1924

2025
"github.com/chainreactors/malice-network/client/assets"
@@ -123,16 +128,27 @@ func (c *Console) Start(bindCmds ...BindCmds) error {
123128
c.InitLocalRPCServer()
124129
}
125130

131+
// Initialize active menu BEFORE headless check.
132+
// MCP/LocalRPC depend on ActiveMenu() returning the correct menu
133+
// (RunCommand calls con.App.Execute(ctx, con.App.ActiveMenu(), args, false)).
126134
if c.Session == nil {
127135
c.App.SwitchMenu(consts.ClientMenu)
128136
} else {
129137
c.SwitchImplant(c.GetInteractive(), consts.CalleeCMD)
130138
}
131-
err := c.App.Start()
132-
if err != nil {
133-
return err
139+
140+
// Headless mode: stdin is not a terminal (e.g., launched by GUI with /dev/null).
141+
// Skip readline loop to avoid busy-spin on MakeRaw(ENOTTY), block on signal instead.
142+
if !term.IsTerminal(int(os.Stdin.Fd())) {
143+
logs.Log.Importantf("running in headless mode (no terminal detected), waiting for signal...")
144+
sig := make(chan os.Signal, 1)
145+
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
146+
<-sig
147+
logs.Log.Importantf("received exit signal, shutting down")
148+
return nil
134149
}
135-
return nil
150+
151+
return c.App.Start()
136152
}
137153

138154
func (c *Console) Context() context.Context {

0 commit comments

Comments
 (0)