@@ -14,6 +14,7 @@ import (
1414// Stdio implements the Transport interface by executing a command
1515// and communicating with it via stdin/stdout using JSON-RPC.
1616type Stdio struct {
17+ process * stdioProcess
1718 command []string
1819 nextID int
1920 debug bool
@@ -38,15 +39,30 @@ func NewStdio(command []string) *Stdio {
3839 }
3940}
4041
42+ // SetCloseAfterExecute toggles whether the underlying process should be closed
43+ // or kept alive after each call to Execute.
44+ func (t * Stdio ) SetCloseAfterExecute (v bool ) {
45+ if v {
46+ t .process = nil
47+ } else {
48+ t .process = & stdioProcess {}
49+ }
50+ }
51+
4152// Execute implements the Transport interface by spawning a subprocess
4253// and communicating with it via JSON-RPC over stdin/stdout.
4354func (t * Stdio ) Execute (method string , params any ) (map [string ]any , error ) {
44- process := & stdioProcess {}
55+ process := t .process
56+ if process == nil {
57+ process = & stdioProcess {}
58+ }
4559
46- var err error
47- process .stdin , process .stdout , process .cmd , process .stderrBuf , err = t .setupCommand ()
48- if err != nil {
49- return nil , err
60+ if process .cmd == nil {
61+ var err error
62+ process .stdin , process .stdout , process .cmd , process .stderrBuf , err = t .setupCommand ()
63+ if err != nil {
64+ return nil , err
65+ }
5066 }
5167
5268 if t .debug {
@@ -94,6 +110,10 @@ func (t *Stdio) Execute(method string, params any) (map[string]any, error) {
94110
95111// closeProcess waits for the command to finish, returning any error.
96112func (t * Stdio ) closeProcess (process * stdioProcess ) error {
113+ if t .process != nil {
114+ return nil
115+ }
116+
97117 _ = process .stdin .Close ()
98118
99119 // Wait for the command to finish with a timeout to prevent zombie processes
0 commit comments