github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/process/manager_exec.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 package process 7 8 import ( 9 "bytes" 10 "context" 11 "io" 12 "os/exec" 13 "time" 14 ) 15 16 // Exec a command and use the default timeout. 17 func (pm *Manager) Exec(desc, cmdName string, args ...string) (string, string, error) { 18 return pm.ExecDir(DefaultContext, -1, "", desc, cmdName, args...) 19 } 20 21 // ExecTimeout a command and use a specific timeout duration. 22 func (pm *Manager) ExecTimeout(timeout time.Duration, desc, cmdName string, args ...string) (string, string, error) { 23 return pm.ExecDir(DefaultContext, timeout, "", desc, cmdName, args...) 24 } 25 26 // ExecDir a command and use the default timeout. 27 func (pm *Manager) ExecDir(ctx context.Context, timeout time.Duration, dir, desc, cmdName string, args ...string) (string, string, error) { 28 return pm.ExecDirEnv(ctx, timeout, dir, desc, nil, cmdName, args...) 29 } 30 31 // ExecDirEnv runs a command in given path and environment variables, and waits for its completion 32 // up to the given timeout (or DefaultTimeout if -1 is given). 33 // Returns its complete stdout and stderr 34 // outputs and an error, if any (including timeout) 35 func (pm *Manager) ExecDirEnv(ctx context.Context, timeout time.Duration, dir, desc string, env []string, cmdName string, args ...string) (string, string, error) { 36 return pm.ExecDirEnvStdIn(ctx, timeout, dir, desc, env, nil, cmdName, args...) 37 } 38 39 // ExecDirEnvStdIn runs a command in given path and environment variables with provided stdIN, and waits for its completion 40 // up to the given timeout (or DefaultTimeout if timeout <= 0 is given). 41 // Returns its complete stdout and stderr 42 // outputs and an error, if any (including timeout) 43 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) { 44 if timeout <= 0 { 45 timeout = 60 * time.Second 46 } 47 48 stdOut := new(bytes.Buffer) 49 stdErr := new(bytes.Buffer) 50 51 ctx, _, finished := pm.AddContextTimeout(ctx, timeout, desc) 52 defer finished() 53 54 cmd := exec.CommandContext(ctx, cmdName, args...) 55 cmd.Dir = dir 56 cmd.Env = env 57 cmd.Stdout = stdOut 58 cmd.Stderr = stdErr 59 if stdIn != nil { 60 cmd.Stdin = stdIn 61 } 62 SetSysProcAttribute(cmd) 63 64 if err := cmd.Start(); err != nil { 65 return "", "", err 66 } 67 68 err := cmd.Wait() 69 if err != nil { 70 err = &Error{ 71 PID: GetPID(ctx), 72 Description: desc, 73 Err: err, 74 CtxErr: ctx.Err(), 75 Stdout: stdOut.String(), 76 Stderr: stdErr.String(), 77 } 78 } 79 80 return stdOut.String(), stdErr.String(), err 81 }