ctlcmd.go 1.2 KB

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