Merge "core: Make cmdline.Command.Main return an exit code instead of exiting."
diff --git a/services/mgmt/device/deviced/main.go b/services/mgmt/device/deviced/main.go
index 710b33f..ddf4714 100644
--- a/services/mgmt/device/deviced/main.go
+++ b/services/mgmt/device/deviced/main.go
@@ -1,6 +1,10 @@
 package main
 
-import "v.io/lib/cmdline"
+import (
+	"os"
+
+	"v.io/lib/cmdline"
+)
 
 func main() {
 	rootCmd := cmdline.Command{
@@ -12,5 +16,5 @@
 		Children: []*cmdline.Command{cmdInstall, cmdUninstall, cmdStart, cmdStop, cmdProfile},
 		Run:      runServer,
 	}
-	rootCmd.Main()
+	os.Exit(rootCmd.Main())
 }
diff --git a/tools/application/main.go b/tools/application/main.go
index 7368a9c..539e0f3 100644
--- a/tools/application/main.go
+++ b/tools/application/main.go
@@ -4,6 +4,8 @@
 package main
 
 import (
+	"os"
+
 	"v.io/core/veyron2"
 	"v.io/core/veyron2/rt"
 
@@ -18,6 +20,7 @@
 	if err != nil {
 		panic(err)
 	}
-	defer runtime.Cleanup()
-	root().Main()
+	exitCode := root().Main()
+	runtime.Cleanup()
+	os.Exit(exitCode)
 }
diff --git a/tools/binary/main.go b/tools/binary/main.go
index 4a57a43..a2b7bfa 100644
--- a/tools/binary/main.go
+++ b/tools/binary/main.go
@@ -4,6 +4,8 @@
 package main
 
 import (
+	"os"
+
 	"v.io/core/veyron2/context"
 	"v.io/core/veyron2/rt"
 
@@ -17,7 +19,8 @@
 	if err != nil {
 		panic(err)
 	}
-	defer runtime.Cleanup()
 	gctx = runtime.NewContext()
-	root().Main()
+	exitCode := root().Main()
+	runtime.Cleanup()
+	os.Exit(exitCode)
 }
diff --git a/tools/build/main.go b/tools/build/main.go
index 7368a9c..049d55b 100644
--- a/tools/build/main.go
+++ b/tools/build/main.go
@@ -4,6 +4,8 @@
 package main
 
 import (
+	"os"
+
 	"v.io/core/veyron2"
 	"v.io/core/veyron2/rt"
 
@@ -18,6 +20,9 @@
 	if err != nil {
 		panic(err)
 	}
-	defer runtime.Cleanup()
-	root().Main()
+
+	exitCode := root().Main()
+	runtime.Cleanup()
+
+	os.Exit(exitCode)
 }
diff --git a/tools/debug/main.go b/tools/debug/main.go
index 7368a9c..cab2605 100644
--- a/tools/debug/main.go
+++ b/tools/debug/main.go
@@ -4,6 +4,8 @@
 package main
 
 import (
+	"os"
+
 	"v.io/core/veyron2"
 	"v.io/core/veyron2/rt"
 
@@ -18,6 +20,8 @@
 	if err != nil {
 		panic(err)
 	}
-	defer runtime.Cleanup()
-	root().Main()
+
+	exitCode := root().Main()
+	runtime.Cleanup()
+	os.Exit(exitCode)
 }
diff --git a/tools/gclogs/main.go b/tools/gclogs/main.go
index aa40b8b..f4f5bb7 100644
--- a/tools/gclogs/main.go
+++ b/tools/gclogs/main.go
@@ -3,6 +3,8 @@
 
 package main
 
+import "os"
+
 func main() {
-	cmdGCLogs.Main()
+	os.Exit(cmdGCLogs.Main())
 }
diff --git a/tools/mgmt/device/main.go b/tools/mgmt/device/main.go
index 4a57a43..c23c137 100644
--- a/tools/mgmt/device/main.go
+++ b/tools/mgmt/device/main.go
@@ -4,6 +4,8 @@
 package main
 
 import (
+	"os"
+
 	"v.io/core/veyron2/context"
 	"v.io/core/veyron2/rt"
 
@@ -17,7 +19,9 @@
 	if err != nil {
 		panic(err)
 	}
-	defer runtime.Cleanup()
 	gctx = runtime.NewContext()
-	root().Main()
+
+	exitCode := root().Main()
+	runtime.Cleanup()
+	os.Exit(exitCode)
 }
diff --git a/tools/mounttable/main.go b/tools/mounttable/main.go
index 7368a9c..cab2605 100644
--- a/tools/mounttable/main.go
+++ b/tools/mounttable/main.go
@@ -4,6 +4,8 @@
 package main
 
 import (
+	"os"
+
 	"v.io/core/veyron2"
 	"v.io/core/veyron2/rt"
 
@@ -18,6 +20,8 @@
 	if err != nil {
 		panic(err)
 	}
-	defer runtime.Cleanup()
-	root().Main()
+
+	exitCode := root().Main()
+	runtime.Cleanup()
+	os.Exit(exitCode)
 }
diff --git a/tools/namespace/main.go b/tools/namespace/main.go
index 7368a9c..539e0f3 100644
--- a/tools/namespace/main.go
+++ b/tools/namespace/main.go
@@ -4,6 +4,8 @@
 package main
 
 import (
+	"os"
+
 	"v.io/core/veyron2"
 	"v.io/core/veyron2/rt"
 
@@ -18,6 +20,7 @@
 	if err != nil {
 		panic(err)
 	}
-	defer runtime.Cleanup()
-	root().Main()
+	exitCode := root().Main()
+	runtime.Cleanup()
+	os.Exit(exitCode)
 }
diff --git a/tools/principal/main.go b/tools/principal/main.go
index ba05ae6..654b897 100644
--- a/tools/principal/main.go
+++ b/tools/principal/main.go
@@ -758,7 +758,7 @@
 		Children: []*cmdline.Command{cmdStoreDefault, cmdStoreSetDefault, cmdStoreForPeer, cmdStoreSet, cmdStoreAddToRoots},
 	}
 
-	(&cmdline.Command{
+	root := &cmdline.Command{
 		Name:  "principal",
 		Short: "Create and manage veyron principals",
 		Long: `
@@ -768,7 +768,8 @@
 All objects are printed using base64-VOM-encoding.
 `,
 		Children: []*cmdline.Command{cmdCreate, cmdFork, cmdSeekBlessings, cmdRecvBlessings, cmdDump, cmdDumpBlessings, cmdBlessSelf, cmdBless, cmdStore},
-	}).Main()
+	}
+	os.Exit(root.Main())
 }
 
 func decodeBlessings(fname string) (security.Blessings, error) {
diff --git a/tools/profile/main.go b/tools/profile/main.go
index 2d9fdae..49f20c5 100644
--- a/tools/profile/main.go
+++ b/tools/profile/main.go
@@ -4,6 +4,8 @@
 package main
 
 import (
+	"os"
+
 	"v.io/core/veyron2"
 	"v.io/core/veyron2/rt"
 
@@ -18,6 +20,8 @@
 	if err != nil {
 		panic(err)
 	}
-	defer runtime.Cleanup()
-	root().Main()
+
+	exitCode := root().Main()
+	runtime.Cleanup()
+	os.Exit(exitCode)
 }
diff --git a/tools/vrpc/vrpc.go b/tools/vrpc/vrpc.go
index 5c025d3..66d7b05 100644
--- a/tools/vrpc/vrpc.go
+++ b/tools/vrpc/vrpc.go
@@ -6,6 +6,7 @@
 import (
 	"fmt"
 	"io"
+	"os"
 	"strings"
 	"time"
 
@@ -31,8 +32,9 @@
 	if err != nil {
 		panic(err)
 	}
-	defer runtime.Cleanup()
-	cmdVRPC.Main()
+	exitCode := cmdVRPC.Main()
+	runtime.Cleanup()
+	os.Exit(exitCode)
 }
 
 var cmdVRPC = &cmdline.Command{
diff --git a/tools/vrun/vrun.go b/tools/vrun/vrun.go
index 8ebdf7c..eb34737 100644
--- a/tools/vrun/vrun.go
+++ b/tools/vrun/vrun.go
@@ -41,7 +41,7 @@
 	cmdVrun.Flags.DurationVar(&durationFlag, "duration", 1*time.Hour, "Duration for the blessing.")
 	cmdVrun.Flags.StringVar(&nameOverride, "name", "", "Name to use for the blessing. Uses the command name if unset.")
 
-	cmdVrun.Main()
+	os.Exit(cmdVrun.Main())
 }
 
 func vrun(cmd *cmdline.Command, args []string) error {