core/sys/sys.go

126 lines
2.3 KiB
Go

package sys
import (
"fmt"
"io"
"os"
"os/exec"
"os/signal"
"syscall"
"golang.org/x/sys/unix"
)
var TERM_WIDTH = 0
func RunCmd(cmd *exec.Cmd) int {
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return ManageStatusCmd(cmd, cmd.Run())
}
func RunShellCmd(call string) int {
cmd := exec.Command("sh", "-c", call)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return ManageStatusCmd(cmd, cmd.Run())
}
func ManageStatusCmd(cmd *exec.Cmd, err error) int {
if err == nil {
return 0
}
// Figure out the exit code
if ws, ok := cmd.ProcessState.Sys().(syscall.WaitStatus); ok {
if ws.Exited() {
return ws.ExitStatus()
}
if ws.Signaled() {
return -int(ws.Signal())
}
}
return -1
}
func RunInteractiveCmd(cmd string, withStderr bool) int {
fmt.Printf(" == go before command : %s\n", cmd)
icmd := exec.Command("bash", "-c", cmd)
icmd.Stdin = os.Stdin
icmd.Stdout = os.Stdout
if withStderr {
icmd.Stderr = os.Stderr
}
return ManageStatusCmd(icmd, icmd.Run())
}
func PipeCmd(cmd1 *exec.Cmd, cmd2 *exec.Cmd, buffers ...io.Writer) {
fmt.Println("> Pipe Commands")
if len(buffers) > 0 {
pr, pw := io.Pipe()
cmd1.Stdout = pw
cmd2.Stdin = pr
cmd2.Stdout = buffers[0]
if len(buffers) > 1 {
cmd2.Stderr = buffers[1]
}
cmd1.Start()
cmd2.Start()
go func() {
defer pw.Close()
err1 := cmd1.Wait()
if err1 != nil {
fmt.Printf("error1 : %v\n", err1)
}
}()
err2 := cmd2.Wait()
if err2 != nil {
fmt.Printf("error2 : %v\n", err2)
}
fmt.Println("< Pipe Commands")
}
}
func UpdateTermSize() error {
ws, err := unix.IoctlGetWinsize(syscall.Stdout, unix.TIOCGWINSZ)
if err != nil {
return err
}
TERM_WIDTH = int(ws.Col)
return nil
}
func HandleTermChange() {
// set signal handler
sigwinch := make(chan os.Signal, 1)
defer close(sigwinch)
signal.Notify(sigwinch, syscall.SIGWINCH)
go func() {
for {
if _, ok := <-sigwinch; !ok {
return
}
_ = UpdateTermSize()
fmt.Printf("TERM WIDTH : %d\n", TERM_WIDTH)
}
}()
}
func HandleSigKill() {
done := make(chan os.Signal, 1)
defer close(done)
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-done // Will block here until user hits ctrl+c
cmd := exec.Command("tput", "cnorm")
RunCmd(cmd)
cmd = exec.Command("tput", "-x", "clear")
RunCmd(cmd)
os.Exit(0)
}()
}