ctlcmd.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. package ctlcmd
  2. import (
  3. "context"
  4. "io"
  5. "os"
  6. "os/exec"
  7. "v2ray.com/core/common/buf"
  8. "v2ray.com/core/common/platform"
  9. "v2ray.com/core/common/signal"
  10. )
  11. //go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg ctlcmd -path Command,Platform,CtlCmd
  12. func Run(args []string, input io.Reader) (buf.MultiBuffer, error) {
  13. v2ctl := platform.GetToolLocation("v2ctl")
  14. if _, err := os.Stat(v2ctl); err != nil {
  15. return nil, err
  16. }
  17. errBuffer := &buf.MultiBuffer{}
  18. cmd := exec.Command(v2ctl, args...)
  19. cmd.Stderr = errBuffer
  20. cmd.SysProcAttr = getSysProcAttr()
  21. if input != nil {
  22. cmd.Stdin = input
  23. }
  24. stdoutReader, err := cmd.StdoutPipe()
  25. if err != nil {
  26. return nil, err
  27. }
  28. defer stdoutReader.Close()
  29. if err := cmd.Start(); err != nil {
  30. return nil, err
  31. }
  32. var content buf.MultiBuffer
  33. loadTask := func() error {
  34. c, err := buf.ReadAllToMultiBuffer(stdoutReader)
  35. if err != nil {
  36. return err
  37. }
  38. content = c
  39. return nil
  40. }
  41. waitTask := func() error {
  42. if err := cmd.Wait(); err != nil {
  43. msg := "failed to execute v2ctl"
  44. if errBuffer.Len() > 0 {
  45. msg += ": " + errBuffer.String()
  46. }
  47. return newError(msg).Base(err)
  48. }
  49. return nil
  50. }
  51. if err := signal.ExecuteParallel(context.Background(), loadTask, waitTask); err != nil {
  52. return nil, err
  53. }
  54. return content, nil
  55. }