summaryrefslogtreecommitdiff
path: root/shell.go
diff options
context:
space:
mode:
Diffstat (limited to 'shell.go')
-rw-r--r--shell.go96
1 files changed, 52 insertions, 44 deletions
diff --git a/shell.go b/shell.go
index d9ee33f..bfdac21 100644
--- a/shell.go
+++ b/shell.go
@@ -16,6 +16,7 @@ var shellStdout *os.File
var shellStderr *os.File
var spewOn bool = false
+var msecDelay int = 20 // number of milliseconds to delay between reads with no data
func Script(cmds string) int {
// split on new lines (while we are at it, handle stupid windows text files
@@ -40,6 +41,10 @@ func SpewOn() {
spewOn = true
}
+func SetDelayInMsec(msecs int) {
+ msecDelay = msecs
+}
+
func SetStdout(newout *os.File) {
shellStdout = newout
}
@@ -85,74 +90,45 @@ func Run(cmdline string) int {
newreader := bufio.NewReader(pstdout)
nbr := nbreader.NewNBReader(newreader, 1024)
- newerrreader := bufio.NewReader(pstderr)
- nbrerr := nbreader.NewNBReader(newerrreader, 1024)
+ // nbrerr := nbreader.NewNBReader(newerrreader, 1024)
+
+ tmp := bufio.NewReader(pstderr)
+ go NonBlockingReader(tmp, shellStderr)
totalCount := 0
- for {
- time.Sleep(2 * time.Millisecond) // only check the buffer 500 times a second
+ var dead bool = false
+ for (dead == false) {
+ time.Sleep(time.Duration(msecDelay) * time.Millisecond) // only check the buffer 500 times a second
// log.Println("sleep done")
+ var empty bool = false
// tight loop that reads 1K at a time until buffer is empty
- for {
+ for (empty == false) {
oneByte := make([]byte, 1024)
count, err := nbr.Read(oneByte)
totalCount += count
if (err != nil) {
- // log.Println("Read() count = ", count, "err = ", err)
+ log.Println("Read() count = ", count, "err = ", err)
oneByte = make([]byte, 1024)
count, err = nbr.Read(oneByte)
f.Write([]byte(string(oneByte)))
f.Flush()
+ empty = true
+ dead = true
}
f.Write([]byte(string(oneByte)))
f.Flush()
if (count == 0) {
- break
+ empty = true
}
}
if (totalCount != 0) {
- log.Println("totalCount = ", totalCount)
- }
-
- //
- // HANDLE STDERR
- // HANDLE STDERR
- //
- oneByte := make([]byte, 1024)
- count, err := nbrerr.Read(oneByte)
-
- if (err != nil) {
- oneByte = make([]byte, 1024)
- count, err = nbrerr.Read(oneByte)
- f.Write([]byte(string(oneByte)))
- f.Flush()
-
- log.Println("Read() count = ", count, "err = ", err)
- // spew.Dump(process.Process)
- // spew.Dump(process.ProcessState)
- err := process.Wait()
- if err != nil {
- if (spewOn) {
- spew.Dump(err.(*exec.ExitError))
- spew.Dump(process.ProcessState)
- }
- stuff := err.(*exec.ExitError)
- log.Println("ERROR ", stuff)
- log.Println("END ", cmdline)
- return -1
- }
- log.Println("END ", cmdline)
- return 0
- } else {
- f.Write([]byte(string(oneByte)))
- f.Flush()
+ log.Println("STDOUT: totalCount = ", totalCount)
+ totalCount = 0
}
-
- // spew.Dump(reflect.ValueOf(cmd.Process).Elem())
}
err := process.Wait()
@@ -177,3 +153,35 @@ func Daemon(cmdline string, timeout time.Duration) int {
time.Sleep(timeout)
}
}
+
+// pass in two file handles (1 read, 1 write)
+func NonBlockingReader(buffReader *bufio.Reader, writeFileHandle *os.File) {
+ // newreader := bufio.NewReader(readFileHandle)
+
+ // create a nonblocking GO reader
+ nbr := nbreader.NewNBReader(buffReader, 1024)
+
+ for {
+ // defer buffReader.Close()
+ // defer writeFileHandle.Flush()
+ defer writeFileHandle.Close()
+ totalCount := 0
+ for {
+ oneByte := make([]byte, 1024)
+ count, err := nbr.Read(oneByte)
+ if (err != nil) {
+ log.Println("count, err =", count, err)
+ return
+ }
+ totalCount += count
+ if (count == 0) {
+ time.Sleep(time.Duration(msecDelay) * time.Millisecond) // without this delay this will peg the CPU
+ if (totalCount != 0) {
+ log.Println("STDERR: totalCount = ", totalCount)
+ totalCount = 0
+ }
+ }
+ writeFileHandle.Write([]byte(string(oneByte)))
+ }
+ }
+}