summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example1/Makefile3
-rwxr-xr-xexample1/example1bin0 -> 3187896 bytes
-rw-r--r--example1/main.go27
-rw-r--r--shell.go96
4 files changed, 82 insertions, 44 deletions
diff --git a/example1/Makefile b/example1/Makefile
new file mode 100644
index 0000000..9fc318d
--- /dev/null
+++ b/example1/Makefile
@@ -0,0 +1,3 @@
+all:
+ go build
+ ./example1
diff --git a/example1/example1 b/example1/example1
new file mode 100755
index 0000000..625385e
--- /dev/null
+++ b/example1/example1
Binary files differ
diff --git a/example1/main.go b/example1/main.go
new file mode 100644
index 0000000..4a36503
--- /dev/null
+++ b/example1/main.go
@@ -0,0 +1,27 @@
+package main
+
+/*
+import "log"
+import "reflect"
+import "os"
+*/
+
+// import "github.com/davecgh/go-spew/spew"
+
+import "git.wit.com/jcarr/shell"
+
+func main() {
+ shell.SpewOn()
+
+ shell.Run("ls /tmp")
+
+ shell.Run("ping -c 4 localhost")
+
+ // slow down the polling to every 2 seconds
+ shell.SetDelayInMsec(2000)
+ shell.Run("ping -c 4 localhost")
+
+ // TODO: this might not be working
+ // check error handling
+ shell.Run("ls /tmpthisisnothere")
+}
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)))
+ }
+ }
+}