github.com/xmplusdev/xray-core@v1.8.10/common/platform/ctlcmd/ctlcmd.go (about) 1 package ctlcmd 2 3 import ( 4 "io" 5 "os" 6 "os/exec" 7 "strings" 8 9 "github.com/xmplusdev/xray-core/common/buf" 10 "github.com/xmplusdev/xray-core/common/platform" 11 ) 12 13 //go:generate go run github.com/xmplusdev/xray-core/common/errors/errorgen 14 15 func Run(args []string, input io.Reader) (buf.MultiBuffer, error) { 16 xctl := platform.GetToolLocation("xctl") 17 if _, err := os.Stat(xctl); err != nil { 18 return nil, newError("xctl doesn't exist").Base(err) 19 } 20 21 var errBuffer buf.MultiBufferContainer 22 var outBuffer buf.MultiBufferContainer 23 24 cmd := exec.Command(xctl, args...) 25 cmd.Stderr = &errBuffer 26 cmd.Stdout = &outBuffer 27 cmd.SysProcAttr = getSysProcAttr() 28 if input != nil { 29 cmd.Stdin = input 30 } 31 32 if err := cmd.Start(); err != nil { 33 return nil, newError("failed to start xctl").Base(err) 34 } 35 36 if err := cmd.Wait(); err != nil { 37 msg := "failed to execute xctl" 38 if errBuffer.Len() > 0 { 39 msg += ": \n" + strings.TrimSpace(errBuffer.MultiBuffer.String()) 40 } 41 return nil, newError(msg).Base(err) 42 } 43 44 // log stderr, info message 45 if !errBuffer.IsEmpty() { 46 newError("<xctl message> \n", strings.TrimSpace(errBuffer.MultiBuffer.String())).AtInfo().WriteToLog() 47 } 48 49 return outBuffer.MultiBuffer, nil 50 }