2022-03-31 20:01:43 +03:00
// Copyright 2022 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2022-03-31 20:01:43 +03:00
package process
import (
"bytes"
"context"
"io"
"os/exec"
"time"
)
// Exec a command and use the default timeout.
func ( pm * Manager ) Exec ( desc , cmdName string , args ... string ) ( string , string , error ) {
return pm . ExecDir ( DefaultContext , - 1 , "" , desc , cmdName , args ... )
}
// ExecTimeout a command and use a specific timeout duration.
func ( pm * Manager ) ExecTimeout ( timeout time . Duration , desc , cmdName string , args ... string ) ( string , string , error ) {
return pm . ExecDir ( DefaultContext , timeout , "" , desc , cmdName , args ... )
}
// ExecDir a command and use the default timeout.
func ( pm * Manager ) ExecDir ( ctx context . Context , timeout time . Duration , dir , desc , cmdName string , args ... string ) ( string , string , error ) {
return pm . ExecDirEnv ( ctx , timeout , dir , desc , nil , cmdName , args ... )
}
// ExecDirEnv runs a command in given path and environment variables, and waits for its completion
// up to the given timeout (or DefaultTimeout if -1 is given).
// Returns its complete stdout and stderr
// outputs and an error, if any (including timeout)
func ( pm * Manager ) ExecDirEnv ( ctx context . Context , timeout time . Duration , dir , desc string , env [ ] string , cmdName string , args ... string ) ( string , string , error ) {
return pm . ExecDirEnvStdIn ( ctx , timeout , dir , desc , env , nil , cmdName , args ... )
}
// ExecDirEnvStdIn runs a command in given path and environment variables with provided stdIN, and waits for its completion
// up to the given timeout (or DefaultTimeout if timeout <= 0 is given).
// Returns its complete stdout and stderr
// outputs and an error, if any (including timeout)
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 ) {
if timeout <= 0 {
timeout = 60 * time . Second
}
stdOut := new ( bytes . Buffer )
stdErr := new ( bytes . Buffer )
ctx , _ , finished := pm . AddContextTimeout ( ctx , timeout , desc )
defer finished ( )
cmd := exec . CommandContext ( ctx , cmdName , args ... )
cmd . Dir = dir
cmd . Env = env
cmd . Stdout = stdOut
cmd . Stderr = stdErr
if stdIn != nil {
cmd . Stdin = stdIn
}
2022-06-03 17:36:18 +03:00
SetSysProcAttribute ( cmd )
2022-03-31 20:01:43 +03:00
if err := cmd . Start ( ) ; err != nil {
return "" , "" , err
}
err := cmd . Wait ( )
if err != nil {
err = & Error {
PID : GetPID ( ctx ) ,
Description : desc ,
Err : err ,
CtxErr : ctx . Err ( ) ,
Stdout : stdOut . String ( ) ,
Stderr : stdErr . String ( ) ,
}
}
return stdOut . String ( ) , stdErr . String ( ) , err
}