// Copyright (C) 2019 Marius Schellenberger

package core

import (
	"errors"
	"os/exec"
	"time"
)

func Timeout(cmd *exec.Cmd, t time.Duration) (output []byte, err error) {
	done := make(chan error)
	out := make(chan []byte)
	go func() {
		o, e := cmd.Output()
		done <- e
		out <- o
	}()
	select {
	case <-time.After(t):
		e := cmd.Process.Kill()
		<-out
		if e != nil {
			<-done
			err = e
			return
		}
		err = <-done
	case e := <-done:
		exerr, ok := e.(*exec.ExitError)
		if ok {
			err = errors.New(e.Error() + "\n" + string(exerr.Stderr))
		} else {
			err = e
		}
		output = <-out
	}
	return
}
