ctlcmd.go 1.2 KB

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