//
//
// gsh - Go lang based Shell
// (c) 2020 ITS more Co., Ltd.
// 2020-0807 created by SatoxITS (ITS more)
//
package main
import (
"bufio" // https://golang.org/pkg/bufio/
"strings"
"fmt"
//"strconv"
"os"
"time"
"syscall"
"go/types"
"go/token"
)
var LINESIZE = 1024
var PROMPT = "> "
func env(argv []string) {
env := os.Environ()
for _, v := range env {
fmt.Printf("%v\n",v)
}
}
func which(path string) (fullpath string, itis bool){
pathenv, found := os.LookupEnv("PATH")
if found {
dirv := strings.Split(pathenv,":")
for _, dir := range dirv {
fi, err := os.Stat(dir+"/"+path)
if err == nil {
fm := fi.Mode()
if fm.IsRegular() {
//fmt.Printf("%s\n",dir+"/"+path)
return dir+"/"+path, true
}
}
}
}
return "", false
}
func eval(argv []string, nlend bool){
var ai = 1
pfmt := "%s"
if argv[ai][0:1] == "%" {
pfmt = argv[ai]
ai = 2
}
if len(argv) <= ai {
return
}
gocode := strings.Join(argv[ai:]," ");
fset := token.NewFileSet()
rval, _ := types.Eval(fset,nil,token.NoPos,gocode)
fmt.Printf(pfmt,rval.Value)
if nlend { fmt.Printf("\n") }
}
func excommand(exec bool, argv []string) (ret int) {
fullpath, itis := which(argv[0])
if itis == false {
return -1
}
if exec {
syscall.Exec(fullpath,argv,os.Environ())
}else{
start := time.Now()
pa := syscall.ProcAttr {
"",
[]string{},
[]uintptr{os.Stdin.Fd(),os.Stdout.Fd(),os.Stderr.Fd()},
nil,
}
pid, _ := syscall.ForkExec(fullpath,argv,&pa)
//fmt.Printf("[%d]\n",pid); // '&' to be background
syscall.Wait4(pid,nil,0,nil);
end := time.Now()
elps := end.Sub(start);
fmt.Printf("-- %d.%09d s\n",elps/1000000000,elps%1000000000)
}
return 0
}
func main() {
for hi := 0; ; hi++ {
fmt.Printf("%d",hi)
fmt.Print(PROMPT)
reader := bufio.NewReaderSize(os.Stdin,LINESIZE);
line, _, _ := reader.ReadLine()
argv := strings.Split(string(line)," ");
cmd := argv[0]
if cmd == "exit" || cmd == "quit" {
break
}
if cmd == "env" {
env(argv)
continue;
}
if cmd == "eval" {
eval(argv,true)
continue;
}
if cmd == "which" {
which(argv[1]);
continue;
}
if cmd == "exec" {
excommand(true,argv[1:])
continue; // should exit
}
excommand(false,argv)
}
}
//---END---
//