@ -6,13 +6,12 @@ package process
import (
import (
"bytes"
"bytes"
"context"
"errors"
"errors"
"fmt"
"fmt"
"os/exec"
"os/exec"
"sync"
"sync"
"time"
"time"
"code.gitea.io/gitea/modules/log"
)
)
// TODO: This packages still uses a singleton for the Manager.
// TODO: This packages still uses a singleton for the Manager.
@ -101,7 +100,10 @@ func (pm *Manager) ExecDirEnv(timeout time.Duration, dir, desc string, env []str
stdOut := new ( bytes . Buffer )
stdOut := new ( bytes . Buffer )
stdErr := new ( bytes . Buffer )
stdErr := new ( bytes . Buffer )
cmd := exec . Command ( cmdName , args ... )
ctx , cancel := context . WithTimeout ( context . Background ( ) , timeout )
defer cancel ( )
cmd := exec . CommandContext ( ctx , cmdName , args ... )
cmd . Dir = dir
cmd . Dir = dir
cmd . Env = env
cmd . Env = env
cmd . Stdout = stdOut
cmd . Stdout = stdOut
@ -111,30 +113,14 @@ func (pm *Manager) ExecDirEnv(timeout time.Duration, dir, desc string, env []str
}
}
pid := pm . Add ( desc , cmd )
pid := pm . Add ( desc , cmd )
done := make ( chan error )
err := cmd . Wait ( )
go func ( ) {
done <- cmd . Wait ( )
} ( )
var err error
select {
case <- time . After ( timeout ) :
if errKill := pm . Kill ( pid ) ; errKill != nil {
log . Error ( 4 , "exec(%d:%s) failed to kill: %v" , pid , desc , errKill )
}
<- done
return "" , "" , ErrExecTimeout
case err = <- done :
}
pm . Remove ( pid )
pm . Remove ( pid )
if err != nil {
if err != nil {
out := fmt . Errorf ( "exec(%d:%s) failed: %v stdout: %v stderr: %v" , pid , desc , err , stdOut , stdErr )
err = fmt . Errorf ( "exec(%d:%s) failed: %v(%v) stdout: %v stderr: %v" , pid , desc , err , ctx . Err ( ) , stdOut , stdErr )
return stdOut . String ( ) , stdErr . String ( ) , out
}
}
return stdOut . String ( ) , stdErr . String ( ) , nil
return stdOut . String ( ) , stdErr . String ( ) , err
}
}
// Kill and remove a process from list.
// Kill and remove a process from list.