ctlcmd.go 1.2 KB

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