// Copyright 2014 The Gogs Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package process import ( "bytes" "errors" "fmt" "os/exec" "time" "github.com/gogits/gogs/modules/log" ) var ( ErrExecTimeout = errors.New("Process execution timeout") ) // Common timeout. var ( // NOTE: could be custom in config file for default. DEFAULT = 60 * time.Second ) // Process represents a working process inherit from Gogs. type Process struct { Pid int64 // Process ID, not system one. Description string Start time.Time Cmd *exec.Cmd } // List of existing processes. var ( curPid int64 = 1 Processes []*Process ) // Add adds a existing process and returns its PID. func Add(desc string, cmd *exec.Cmd) int64 { pid := curPid Processes = append(Processes, &Process{ Pid: pid, Description: desc, Start: time.Now(), Cmd: cmd, }) curPid++ return pid } // Exec starts executing a command in given path, it records its process and timeout. func ExecDir(timeout time.Duration, dir, desc, cmdName string, args ...string) (string, string, error) { if timeout == -1 { timeout = DEFAULT } bufOut := new(bytes.Buffer) bufErr := new(bytes.Buffer) cmd := exec.Command(cmdName, args...) cmd.Dir = dir cmd.Stdout = bufOut cmd.Stderr = bufErr if err := cmd.Start(); err != nil { return "", err.Error(), err } pid := Add(desc, cmd) done := make(chan error) go func() { done <- cmd.Wait() }() var err error select { case <-time.After(timeout): if errKill := Kill(pid); errKill != nil { log.Error(4, "Exec(%d:%s): %v", pid, desc, errKill) } <-done return "", ErrExecTimeout.Error(), ErrExecTimeout case err = <-done: } Remove(pid) return bufOut.String(), bufErr.String(), err } // Exec starts executing a command, it records its process and timeout. func ExecTimeout(timeout time.Duration, desc, cmdName string, args ...string) (string, string, error) { return ExecDir(timeout, "", desc, cmdName, args...) } // Exec starts executing a command, it records its process and has default timeout. func Exec(desc, cmdName string, args ...string) (string, string, error) { return ExecDir(-1, "", desc, cmdName, args...) } // Remove removes a process from list. func Remove(pid int64) { for i, proc := range Processes { if proc.Pid == pid { Processes = append(Processes[:i], Processes[i+1:]...) return } } } // Kill kills and removes a process from list. func Kill(pid int64) error { for i, proc := range Processes { if proc.Pid == pid { if proc.Cmd != nil && proc.Cmd.Process != nil && proc.Cmd.ProcessState != nil && !proc.Cmd.ProcessState.Exited() { if err := proc.Cmd.Process.Kill(); err != nil { return fmt.Errorf("fail to kill process(%d/%s): %v", proc.Pid, proc.Description, err) } } Processes = append(Processes[:i], Processes[i+1:]...) return nil } } return nil }
session(release): write data/sessions/b/d/bdd02114acd03159: no space left on device
github.com/go-macaron/session@v0.0.0-20190805070824-1a3cdc6f5659/session.go:199 (0x8b2934) gopkg.in/macaron.v1@v1.3.9/context.go:79 (0x83d0a0) github.com/go-macaron/inject@v0.0.0-20160627170012-d8a0b8677191/inject.go:157 (0x80ab07) github.com/go-macaron/inject@v0.0.0-20160627170012-d8a0b8677191/inject.go:135 (0x80a8a8) gopkg.in/macaron.v1@v1.3.9/context.go:121 (0x83d1f8) gopkg.in/macaron.v1@v1.3.9/context.go:112 (0x84fdb5) gopkg.in/macaron.v1@v1.3.9/recovery.go:161 (0x84fda8) gopkg.in/macaron.v1@v1.3.9/logger.go:40 (0x840c73) github.com/go-macaron/inject@v0.0.0-20160627170012-d8a0b8677191/inject.go:157 (0x80ab07) github.com/go-macaron/inject@v0.0.0-20160627170012-d8a0b8677191/inject.go:135 (0x80a8a8) gopkg.in/macaron.v1@v1.3.9/context.go:121 (0x83d1f8) gopkg.in/macaron.v1@v1.3.9/router.go:187 (0x850fc6) gopkg.in/macaron.v1@v1.3.9/router.go:303 (0x8493e5) gopkg.in/macaron.v1@v1.3.9/macaron.go:220 (0x841fca) net/http/server.go:2836 (0x7a79b2) net/http/server.go:1924 (0x7a341b) runtime/asm_amd64.s:1373 (0x46f9f0)