You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

manager_exec.go 2.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package process
  4. import (
  5. "bytes"
  6. "context"
  7. "io"
  8. "os/exec"
  9. "time"
  10. )
  11. // Exec a command and use the default timeout.
  12. func (pm *Manager) Exec(desc, cmdName string, args ...string) (string, string, error) {
  13. return pm.ExecDir(DefaultContext, -1, "", desc, cmdName, args...)
  14. }
  15. // ExecTimeout a command and use a specific timeout duration.
  16. func (pm *Manager) ExecTimeout(timeout time.Duration, desc, cmdName string, args ...string) (string, string, error) {
  17. return pm.ExecDir(DefaultContext, timeout, "", desc, cmdName, args...)
  18. }
  19. // ExecDir a command and use the default timeout.
  20. func (pm *Manager) ExecDir(ctx context.Context, timeout time.Duration, dir, desc, cmdName string, args ...string) (string, string, error) {
  21. return pm.ExecDirEnv(ctx, timeout, dir, desc, nil, cmdName, args...)
  22. }
  23. // ExecDirEnv runs a command in given path and environment variables, and waits for its completion
  24. // up to the given timeout (or DefaultTimeout if -1 is given).
  25. // Returns its complete stdout and stderr
  26. // outputs and an error, if any (including timeout)
  27. func (pm *Manager) ExecDirEnv(ctx context.Context, timeout time.Duration, dir, desc string, env []string, cmdName string, args ...string) (string, string, error) {
  28. return pm.ExecDirEnvStdIn(ctx, timeout, dir, desc, env, nil, cmdName, args...)
  29. }
  30. // ExecDirEnvStdIn runs a command in given path and environment variables with provided stdIN, and waits for its completion
  31. // up to the given timeout (or DefaultTimeout if timeout <= 0 is given).
  32. // Returns its complete stdout and stderr
  33. // outputs and an error, if any (including timeout)
  34. func (pm *Manager) ExecDirEnvStdIn(ctx context.Context, timeout time.Duration, dir, desc string, env []string, stdIn io.Reader, cmdName string, args ...string) (string, string, error) {
  35. if timeout <= 0 {
  36. timeout = 60 * time.Second
  37. }
  38. stdOut := new(bytes.Buffer)
  39. stdErr := new(bytes.Buffer)
  40. ctx, _, finished := pm.AddContextTimeout(ctx, timeout, desc)
  41. defer finished()
  42. cmd := exec.CommandContext(ctx, cmdName, args...)
  43. cmd.Dir = dir
  44. cmd.Env = env
  45. cmd.Stdout = stdOut
  46. cmd.Stderr = stdErr
  47. if stdIn != nil {
  48. cmd.Stdin = stdIn
  49. }
  50. SetSysProcAttribute(cmd)
  51. if err := cmd.Start(); err != nil {
  52. return "", "", err
  53. }
  54. err := cmd.Wait()
  55. if err != nil {
  56. err = &Error{
  57. PID: GetPID(ctx),
  58. Description: desc,
  59. Err: err,
  60. CtxErr: ctx.Err(),
  61. Stdout: stdOut.String(),
  62. Stderr: stdErr.String(),
  63. }
  64. }
  65. return stdOut.String(), stdErr.String(), err
  66. }