boot v2 progress: disks, ssh, success...

This commit is contained in:
Mikaël Cluseau
2022-03-08 11:45:56 +01:00
parent 8e86579004
commit 8506f8807d
38 changed files with 1767 additions and 113 deletions

118
shio/shio.go Normal file
View File

@ -0,0 +1,118 @@
// Shared IO
package shio
import (
"io"
"sync"
"novit.nc/direktil/initrd/colorio"
)
type ShIO struct {
buf []byte
closed bool
cond *sync.Cond
hideInput bool
}
func New() *ShIO {
return NewWithCap(1024)
}
func NewWithCap(capacity int) *ShIO {
return NewWithBytes(make([]byte, 0, capacity))
}
func NewWithBytes(content []byte) *ShIO {
return &ShIO{
buf: content,
cond: sync.NewCond(&sync.Mutex{}),
}
}
var (
_ io.WriteCloser = New()
)
func (s *ShIO) Write(data []byte) (n int, err error) {
s.cond.L.Lock()
defer s.cond.L.Unlock()
if s.closed {
err = io.EOF
return
}
if s.hideInput {
s.buf = append(s.buf, colorio.Reset...)
}
s.buf = append(s.buf, data...)
n = len(data)
if s.hideInput {
s.buf = append(s.buf, colorio.Hidden...)
}
s.cond.Broadcast()
return
}
func (s *ShIO) HideInput() {
s.cond.L.Lock()
defer s.cond.L.Unlock()
if s.closed {
return
}
s.buf = append(s.buf, colorio.Hidden...)
s.hideInput = true
}
func (s *ShIO) ShowInput() {
s.cond.L.Lock()
defer s.cond.L.Unlock()
if s.closed {
return
}
s.buf = append(s.buf, colorio.Reset...)
s.hideInput = false
}
func (s *ShIO) Close() (err error) {
s.cond.L.Lock()
defer s.cond.L.Unlock()
s.closed = true
s.cond.Broadcast()
return
}
func (s *ShIO) NewReader() io.Reader {
return &shioReader{s, 0}
}
type shioReader struct {
in *ShIO
pos int
}
func (r *shioReader) Read(ba []byte) (n int, err error) {
r.in.cond.L.Lock()
defer r.in.cond.L.Unlock()
for r.pos == len(r.in.buf) && !r.in.closed {
r.in.cond.Wait()
}
if r.pos == len(r.in.buf) && r.in.closed {
err = io.EOF
return
}
n = copy(ba, r.in.buf[r.pos:])
r.pos += n
return
}

52
shio/shio_test.go Normal file
View File

@ -0,0 +1,52 @@
package shio
import (
"fmt"
"io"
"os"
"sync"
"time"
)
func ExampleOutput() {
done := false
defer func() { done = true }()
go func() {
time.Sleep(time.Second)
if !done {
panic("timeout")
}
}()
shio := NewWithCap(3)
r1 := shio.NewReader()
// read as you write
wg := new(sync.WaitGroup)
wg.Add(1)
go func() {
defer wg.Done()
io.Copy(os.Stdout, r1)
fmt.Println("-- r1 done --")
}()
fmt.Fprintln(shio, "hello1")
fmt.Fprintln(shio, "hello2")
shio.Close()
wg.Wait()
// read after close
r2 := shio.NewReader()
io.Copy(os.Stdout, r2)
fmt.Println("-- r2 done --")
// Output:
// hello1
// hello2
// -- r1 done --
// hello1
// hello2
// -- r2 done --
}