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