veyron/lib/flags,veyron/lib/exec: pipe parent config opts to child's flags parse

This change adds a way to override flags in the child via the parent config object passed through the vanadium exec mechanism.

Specifically, lib/flags.Parse gets a new argument (config), which overrides/adds
flag values after parsing the command-line args. The runtime grabs the config from the exec handle and passes it to Parse.

Sundry test cases to test the new logic added.

Change-Id: Ied173b770e375d6d36e5de8076219e20bd682fba
diff --git a/lib/exec/child.go b/lib/exec/child.go
index 72678d9..80ebfd2 100644
--- a/lib/exec/child.go
+++ b/lib/exec/child.go
@@ -55,6 +55,11 @@
 	return childHandle, childHandleErr
 }
 
+// TODO(caprita): There's nothing preventing SetReady and SetFailed from being
+// called multiple times (e.g. from different instances of the runtime
+// intializing themselves).  This results in errors for all but the first
+// invocation. Should we instead run these with sync.Once?
+
 // SetReady writes a 'ready' status to its parent.
 func (c *ChildHandle) SetReady() error {
 	_, err := c.statusPipe.Write([]byte(readyStatus))
diff --git a/lib/exec/config.go b/lib/exec/config.go
index aae2c26..52c622f 100644
--- a/lib/exec/config.go
+++ b/lib/exec/config.go
@@ -38,6 +38,8 @@
 	// values for keys that already exist and creating new key-value pairs
 	// for keys that don't.
 	MergeFrom(string) error
+	// Dump returns the config information as a map from ket to value.
+	Dump() map[string]string
 }
 
 type cfg struct {
@@ -66,6 +68,16 @@
 	return v, nil
 }
 
+func (c cfg) Dump() (res map[string]string) {
+	res = make(map[string]string)
+	c.RLock()
+	defer c.RUnlock()
+	for k, v := range c.m {
+		res[k] = v
+	}
+	return
+}
+
 func (c cfg) Clear(key string) {
 	c.Lock()
 	defer c.Unlock()
diff --git a/lib/exec/config_test.go b/lib/exec/config_test.go
index 2580078..cfd2637 100644
--- a/lib/exec/config_test.go
+++ b/lib/exec/config_test.go
@@ -1,7 +1,9 @@
 package exec
 
 import (
+	"reflect"
 	"testing"
+
 	"v.io/core/veyron2/verror2"
 )
 
@@ -29,6 +31,9 @@
 	checkPresent(t, c, "foo", "baz")
 	c.Clear("foo")
 	checkAbsent(t, c, "foo")
+	if want, got := map[string]string{}, c.Dump(); !reflect.DeepEqual(want, got) {
+		t.Errorf("Expected %v for Dump, got %v instead", want, got)
+	}
 }
 
 // TestSerialize checks that serializing the config and merging from a
@@ -65,4 +70,7 @@
 	checkPresent(t, readC, "k2", "v2")
 	checkPresent(t, readC, "k3", "v3")
 	checkPresent(t, readC, "k4", "v4")
+	if want, got := map[string]string{"k1": "newv1", "k2": "v2", "k3": "v3", "k4": "v4"}, readC.Dump(); !reflect.DeepEqual(want, got) {
+		t.Errorf("Expected %v for Dump, got %v instead", want, got)
+	}
 }