forked from u-root/u-root
/
main.go
119 lines (112 loc) · 2.22 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright 2012-2018 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"flag"
"io"
"log"
"os"
"os/exec"
"github.com/u-root/u-root/pkg/complete"
"github.com/u-root/u-root/pkg/termios"
)
var (
debug = flag.Bool("d", false, "enable debug prints")
v = func(string, ...interface{}) {}
)
func verbose(f string, a ...interface{}) {
v(f+"\r\n", a...)
}
func output(r io.Reader, w io.Writer) {
for {
var b [1]byte
n, err := r.Read(b[:])
if err == io.EOF {
return
}
if err != nil {
log.Printf("output: %v", err)
return
}
if n < len(b) {
continue
}
var s string
switch b[0] {
default:
s = string(b[:])
case '\b', 127:
s = "\b \b"
case '\r', '\n':
s = "\r\n"
}
if _, err := w.Write([]byte(s)); err != nil {
log.Printf("output write: %v", err)
return
}
}
}
func main() {
flag.Parse()
if *debug {
v = log.Printf
complete.Debug = verbose
}
t, err := termios.New()
if err != nil {
log.Fatal(err)
}
r, err := t.Raw()
if err != nil {
log.Printf("non-fatal cannot get tty: %v", err)
}
defer t.Set(r)
cr, cw, err := os.Pipe()
if err != nil {
log.Fatal(err)
}
go output(cr, t)
for {
p, err := complete.NewPathCompleter()
if err != nil {
log.Fatal(err)
}
c := complete.NewMultiCompleter(complete.NewStringCompleter([]string{"exit"}), p)
l := complete.NewLineReader(c, t, cw)
s, err := l.ReadOne()
v("ash: Readone: %v, %v", s, err)
if err != nil && err != complete.EOL {
log.Print(err)
continue
}
if len(s) == 0 {
continue
}
if s[0] == "exit" {
break
}
// s[0] is either the match or what they typed so far.
cw.Write([]byte(" "))
bin := s[0]
var args []string
for err == nil {
c := complete.NewFileCompleter("")
l := complete.NewLineReader(c, t, t)
s, err := l.ReadOne()
v("ash: l.ReadOne returns %v, %v", s, err)
args = append(args, s...)
v("ash: add %v", s)
if err != nil {
log.Print(err)
break
}
}
v("ash: Done reading args")
cmd := exec.Command(bin, args...)
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, cw, cw
if err := cmd.Run(); err != nil {
log.Print(err)
}
}
}