Repository: mesos
Updated Branches:
  refs/heads/master f855fb7f2 -> 4cc0ffc4e


Refactoring to use FlagsBase common functionality.

Jira: MESOS-2711

All the main() methods have been refactored to use the definition of
FlagsBase::help flag and FlagsBase::usage().

This CL also tries to bring some uniformity to the use of exit codes:
if this is deemed to be worth making it uniform, we can come up with
common rules and extend the changes here to be compliant.

This touches a lot of files, but keep scrolling, and you will see a
pattern emerge.

Review: https://reviews.apache.org/r/34195


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/4cc0ffc4
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/4cc0ffc4
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/4cc0ffc4

Branch: refs/heads/master
Commit: 4cc0ffc4e5198af8bec78dca892b021f6b07d908
Parents: 1694bda
Author: Marco Massenzio <[email protected]>
Authored: Mon Jun 1 10:53:59 2015 -0700
Committer: Benjamin Hindman <[email protected]>
Committed: Mon Jun 1 15:59:38 2015 -0700

----------------------------------------------------------------------
 src/cli/execute.cpp                             |  66 +++++-------
 src/cli/mesos.cpp                               |  10 +-
 src/cli/resolve.cpp                             |  77 ++++----------
 src/docker/executor.cpp                         |  57 ++++------
 src/examples/load_generator_framework.cpp       |  38 +++----
 src/examples/low_level_scheduler_libprocess.cpp |   2 +-
 src/examples/low_level_scheduler_pthread.cpp    |   2 +-
 src/examples/persistent_volume_framework.cpp    |  31 ++----
 src/health-check/main.cpp                       |  66 ++++++------
 src/launcher/executor.cpp                       |  28 ++---
 src/local/main.cpp                              |  35 ++-----
 src/log/tool/benchmark.cpp                      |  51 ++++-----
 src/log/tool/benchmark.hpp                      |   3 -
 src/log/tool/initialize.cpp                     |  37 ++-----
 src/log/tool/initialize.hpp                     |   3 -
 src/log/tool/read.cpp                           |  35 ++-----
 src/log/tool/read.hpp                           |   3 -
 src/log/tool/replica.cpp                        |  40 +++----
 src/log/tool/replica.hpp                        |   3 -
 src/master/main.cpp                             | 103 +++++++++----------
 .../isolators/network/port_mapping.cpp          |  10 --
 .../isolators/network/port_mapping.hpp          |   2 -
 src/slave/main.cpp                              |  58 +++++------
 src/tests/main.cpp                              |  35 ++-----
 src/usage/main.cpp                              |  37 ++-----
 25 files changed, 282 insertions(+), 550 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/cli/execute.cpp
----------------------------------------------------------------------
diff --git a/src/cli/execute.cpp b/src/cli/execute.cpp
index dbd19e6..b387b64 100644
--- a/src/cli/execute.cpp
+++ b/src/cli/execute.cpp
@@ -50,15 +50,6 @@ using std::string;
 using std::vector;
 
 
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
-  cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
-       << endl
-       << "Supported options:" << endl
-       << flags.usage();
-}
-
-
 class Flags : public flags::FlagsBase
 {
 public:
@@ -287,50 +278,43 @@ int main(int argc, char** argv)
 {
   Flags flags;
 
-  bool help;
-  flags.add(&help,
-            "help",
-            "Prints this help message",
-            false);
-
   // Load flags from environment and command line.
   Try<Nothing> load = flags.load(None(), argc, argv);
 
   if (load.isError()) {
-    cerr << load.error() << endl;
-    usage(argv[0], flags);
-    return -1;
+    cerr << flags.usage(load.error()) << endl;
+    return EXIT_FAILURE;
   }
 
-  if (help) {
-    usage(argv[0], flags);
-    return -1;
+  // TODO(marco): this should be encapsulated entirely into the
+  // FlagsBase API - possibly with a 'guard' that prevents FlagsBase
+  // from calling ::exit(EXIT_FAILURE) after calling usage() (which
+  // would be the default behavior); see MESOS-2766.
+  if (flags.help) {
+    cout << flags.usage() << endl;
+    return EXIT_SUCCESS;
   }
 
   if (flags.master.isNone()) {
-    cerr << "Missing --master=IP:PORT" << endl;
-    usage(argv[0], flags);
-    return -1;
+    cerr << flags.usage("Missing required option --master") << endl;
+    return EXIT_FAILURE;
   }
 
   UPID master("master@" + flags.master.get());
-
   if (!master) {
-    cerr << "Could not parse --master=" << flags.master.get() << endl;
-    usage(argv[0], flags);
-    return -1;
+    cerr << flags.usage("Could not parse --master=" + flags.master.get())
+         << endl;
+    return EXIT_FAILURE;
   }
 
   if (flags.name.isNone()) {
-    cerr << "Missing --name=NAME" << endl;
-    usage(argv[0], flags);
-    return -1;
+    cerr << flags.usage("Missing required option --name") << endl;
+    return EXIT_FAILURE;
   }
 
   if (flags.command.isNone()) {
-    cerr << "Missing --command=COMMAND" << endl;
-    usage(argv[0], flags);
-    return -1;
+    cerr << flags.usage("Missing required option --command") << endl;
+    return EXIT_FAILURE;
   }
 
   Result<string> user = os::user();
@@ -340,10 +324,10 @@ int main(int argc, char** argv)
     } else {
       cerr << "No username for uid " << ::getuid() << endl;
     }
-    return -1;
+    return EXIT_FAILURE;
   }
 
-  Option<hashmap<string, string>> environment;
+  Option<hashmap<string, string>> environment = None();
 
   if (flags.environment.isSome()) {
     environment = flags.environment.get();
@@ -370,22 +354,22 @@ int main(int argc, char** argv)
     Try<bool> exists = hdfs.exists(path);
     if (exists.isError()) {
       cerr << "Failed to check if file exists: " << exists.error() << endl;
-      return -1;
+      return EXIT_FAILURE;
     } else if (exists.get() && flags.overwrite) {
       Try<Nothing> rm = hdfs.rm(path);
       if (rm.isError()) {
         cerr << "Failed to remove existing file: " << rm.error() << endl;
-        return -1;
+        return EXIT_FAILURE;
       }
     } else if (exists.get()) {
       cerr << "File already exists (see --overwrite)" << endl;
-      return -1;
+      return EXIT_FAILURE;
     }
 
     Try<Nothing> copy = hdfs.copyFromLocal(flags.package.get(), path);
     if (copy.isError()) {
       cerr << "Failed to copy package: " << copy.error() << endl;
-      return -1;
+      return EXIT_FAILURE;
     }
 
     // Now save the URI.
@@ -413,5 +397,5 @@ int main(int argc, char** argv)
 
   MesosSchedulerDriver driver(&scheduler, framework, flags.master.get());
 
-  return driver.run() == DRIVER_STOPPED ? 0 : 1;
+  return driver.run() == DRIVER_STOPPED ? EXIT_SUCCESS : EXIT_FAILURE;
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/cli/mesos.cpp
----------------------------------------------------------------------
diff --git a/src/cli/mesos.cpp b/src/cli/mesos.cpp
index 171a707..1121e19 100644
--- a/src/cli/mesos.cpp
+++ b/src/cli/mesos.cpp
@@ -65,7 +65,7 @@ int main(int argc, char** argv)
 
   if (argc < 2) {
     usage(argv[0]);
-    exit(1);
+    return EXIT_FAILURE;
   }
 
   // Update PYTHONPATH to include path to installed 'mesos' module.
@@ -78,7 +78,7 @@ int main(int argc, char** argv)
   if (string(argv[1]) == "help") {
     if (argc == 2) {
       usage(argv[0]);
-      return 0;
+      return EXIT_SUCCESS;
     } else {
       // 'mesos help command' => 'mesos command --help'
       argv[1] = argv[2];
@@ -88,7 +88,7 @@ int main(int argc, char** argv)
   } else if (string(argv[1]).find("--") == 0) {
     cerr << "Not expecting '" << argv[1] << "' before command" << endl;
     usage(argv[0]);
-    return -1;
+    return EXIT_FAILURE;
   } else {
     string command = argv[1];
     string executable = "mesos-" + command;
@@ -101,8 +101,8 @@ int main(int argc, char** argv)
       cerr << "Failed to execute " << command
            << ": " << strerror(errno) << endl;
     }
-    return -1;
+    return EXIT_FAILURE;
   }
 
-  return 0;
+  return EXIT_SUCCESS;
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/cli/resolve.cpp
----------------------------------------------------------------------
diff --git a/src/cli/resolve.cpp b/src/cli/resolve.cpp
index a99b609..74545a0 100644
--- a/src/cli/resolve.cpp
+++ b/src/cli/resolve.cpp
@@ -43,24 +43,10 @@ using std::endl;
 using std::string;
 
 
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
-  cerr << "Usage: " << os::basename(argv0).get() << " <master>" << endl
-       << endl
-       << "Supported options:" << endl
-       << flags.usage();
-}
-
-
 int main(int argc, char** argv)
 {
   flags::FlagsBase flags;
-
-  bool help;
-  flags.add(&help,
-            "help",
-            "Prints this help message",
-            false);
+  flags.setUsageMessage("Usage: " + os::basename(argv[0]).get() + " <master>");
 
   Duration timeout;
   flags.add(&timeout,
@@ -68,75 +54,54 @@ int main(int argc, char** argv)
             "How long to wait to resolve master",
             Seconds(5));
 
+  // TODO(marco): `verbose` is also a great candidate for FlagsBase.
   bool verbose;
   flags.add(&verbose,
             "verbose",
             "Be verbose",
             false);
 
-  // Load flags from environment and command line.
-  Try<Nothing> load = flags.load(None(), argc, argv);
+  // Load flags from environment and command line, and remove
+  // them from argv.
+  Try<Nothing> load = flags.load(None(), &argc, &argv);
 
   if (load.isError()) {
-    cerr << load.error() << endl;
-    usage(argv[0], flags);
-    return -1;
-  }
-
-  if (help) {
-    usage(argv[0], flags);
-    return -1;
-  }
-
-  if (argc < 2) {
-    usage(argv[0], flags);
-    return -1;
+    cerr << flags.usage(load.error()) << endl;
+    return EXIT_FAILURE;
   }
 
-  Option<string> master = None();
-
-  // Find 'master' argument (the only argument not prefixed by '--').
-  for (int i = 1; i < argc; i++) {
-    const std::string arg(strings::trim(argv[i]));
-    if (arg.find("--") != 0) {
-      if (master.isSome()) {
-        // There should only be one non-flag argument.
-        cerr << "Ambiguous 'master': "
-             << master.get() << " and " << arg << endl;
-        usage(argv[0], flags);
-        return -1;
-      } else {
-        master = arg;
-      }
-    }
+  if (flags.help) {
+    cout << flags.usage() << endl;
+    return EXIT_SUCCESS;
   }
 
-  if (master.isNone()) {
-    cerr << "Missing 'master'" << endl;
-    usage(argv[0], flags);
-    return -1;
+  // 'master' argument must be the only argument left after parsing.
+  if (argc != 2) {
+    cerr << flags.usage("There must be only one argument: <master>") << endl;
+    return EXIT_FAILURE;
   }
 
-  Try<MasterDetector*> detector = MasterDetector::create(master.get());
+  string master = argv[1];
+  Try<MasterDetector*> detector = MasterDetector::create(master);
 
   if (detector.isError()) {
     cerr << "Failed to create a master detector: " << detector.error() << endl;
-    return -1;
+    return EXIT_FAILURE;
   }
 
   Future<Option<MasterInfo> > masterInfo = detector.get()->detect();
 
   if (!masterInfo.await(timeout)) {
-    cerr << "Failed to detect master from '" << master.get()
+    cerr << "Failed to detect master from '" << master
          << "' within " << timeout << endl;
     return -1;
   } else {
     CHECK(!masterInfo.isDiscarded());
 
     if (masterInfo.isFailed()) {
-      cerr << "Failed to detect master from '" << master.get()
+      cerr << "Failed to detect master from '" << master
            << "': " << masterInfo.failure() << endl;
-      return -1;
+      return EXIT_FAILURE;
     }
   }
 
@@ -144,5 +109,5 @@ int main(int argc, char** argv)
   CHECK_SOME(masterInfo.get());
   cout << strings::remove(masterInfo.get().get().pid(), "master@") << endl;
 
-  return 0;
+  return EXIT_SUCCESS;
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/docker/executor.cpp
----------------------------------------------------------------------
diff --git a/src/docker/executor.cpp b/src/docker/executor.cpp
index 709fbe3..cdcd8ee 100644
--- a/src/docker/executor.cpp
+++ b/src/docker/executor.cpp
@@ -348,75 +348,54 @@ private:
 } // namespace mesos {
 
 
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
-  cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
-       << endl
-       << "Supported options:" << endl
-       << flags.usage();
-}
-
-
 int main(int argc, char** argv)
 {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   mesos::internal::docker::Flags flags;
 
-  bool help;
-  flags.add(&help,
-            "help",
-            "Prints this help message",
-            false);
-
   // Load flags from environment and command line.
   Try<Nothing> load = flags.load(None(), &argc, &argv);
 
   if (load.isError()) {
-    cerr << load.error() << endl;
-    usage(argv[0], flags);
-    return -1;
+    cerr << flags.usage(load.error()) << endl;
+    return EXIT_FAILURE;
   }
 
   std::cout << stringify(flags) << std::endl;
 
   mesos::internal::logging::initialize(argv[0], flags, true); // Catch signals.
 
-  if (help) {
-    usage(argv[0], flags);
-    return -1;
+  if (flags.help) {
+    cout << flags.usage() << endl;
+    return EXIT_SUCCESS;
   }
 
   std::cout << stringify(flags) << std::endl;
 
   if (flags.docker.isNone()) {
-    LOG(WARNING) << "Expected docker executable path";
-    usage(argv[0], flags);
-    return 0;
+    cerr << flags.usage("Missing required option --docker") << endl;
+    return EXIT_FAILURE;
   }
 
   if (flags.container.isNone()) {
-    LOG(WARNING) << "Expected container name";
-    usage(argv[0], flags);
-    return 0;
+    cerr << flags.usage("Missing required option --container") << endl;
+    return EXIT_FAILURE;
   }
 
   if (flags.sandbox_directory.isNone()) {
-    LOG(WARNING) << "Expected sandbox directory path";
-    usage(argv[0], flags);
-    return 0;
+    cerr << flags.usage("Missing required option --sandbox_directory") << endl;
+    return EXIT_FAILURE;
   }
 
   if (flags.mapped_directory.isNone()) {
-    LOG(WARNING) << "Expected mapped sandbox directory path";
-    usage(argv[0], flags);
-    return 0;
+    cerr << flags.usage("Missing required option --mapped_directory") << endl;
+    return EXIT_FAILURE;
   }
 
   if (flags.stop_timeout.isNone()) {
-    LOG(WARNING) << "Expected stop timeout";
-    usage(argv[0], flags);
-    return 0;
+    cerr << flags.usage("Missing required option --stop_timeout") << endl;
+    return EXIT_FAILURE;
   }
 
   // The 2nd argument for docker create is set to false so we skip
@@ -424,8 +403,8 @@ int main(int argc, char** argv)
   // should have already validated docker.
   Try<Docker*> docker = Docker::create(flags.docker.get(), false);
   if (docker.isError()) {
-    LOG(WARNING) << "Unable to create docker abstraction: " << docker.error();
-    return -1;
+    cerr << "Unable to create docker abstraction: " << docker.error() << endl;
+    return EXIT_FAILURE;
   }
 
   mesos::internal::docker::DockerExecutor executor(
@@ -436,5 +415,5 @@ int main(int argc, char** argv)
       flags.stop_timeout.get());
 
   mesos::MesosExecutorDriver driver(&executor);
-  return driver.run() == mesos::DRIVER_STOPPED ? 0 : 1;
+  return driver.run() == mesos::DRIVER_STOPPED ? EXIT_SUCCESS : EXIT_FAILURE;
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/examples/load_generator_framework.cpp
----------------------------------------------------------------------
diff --git a/src/examples/load_generator_framework.cpp 
b/src/examples/load_generator_framework.cpp
index be1a3bf..6e83308 100644
--- a/src/examples/load_generator_framework.cpp
+++ b/src/examples/load_generator_framework.cpp
@@ -270,32 +270,17 @@ public:
         "Run LoadGenerator for the specified duration.\n"
         "Without this option this framework would keep generating load\n"
         "forever as long as it is connected to the master");
-
-    add(&Flags::help,
-        "help",
-        "Print this help message",
-        false);
   }
 
   Option<string> master;
   string principal;
   Option<string> secret;
   bool authenticate;
-  bool help;
   Option<double> qps;
   Option<Duration> duration;
 };
 
 
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
-  cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
-       << endl
-       << "Supported options:" << endl
-       << flags.usage();
-}
-
-
 int main(int argc, char** argv)
 {
   Flags flags;
@@ -303,26 +288,28 @@ int main(int argc, char** argv)
   Try<Nothing> load = flags.load("MESOS_", argc, argv);
 
   if (load.isError()) {
-    cerr << load.error() << endl;
-    usage(argv[0], flags);
-    exit(1);
+    cerr << flags.usage(load.error()) << endl;
+    return EXIT_FAILURE;
   }
 
   if (flags.help) {
-    usage(argv[0], flags);
-    exit(1);
+    cout << flags.usage() << endl;
+    return EXIT_SUCCESS;
   }
 
   if (flags.master.isNone()) {
-    EXIT(1) << "Missing required option --master. See --help";
+    cerr << flags.usage( "Missing required option --master") << endl;
+    return EXIT_FAILURE;
   }
 
   if (flags.qps.isNone()) {
-    EXIT(1) << "Missing required option --qps. See --help";
+    cerr << flags.usage("Missing required option --qps") << endl;
+    return EXIT_FAILURE;
   }
 
   if (flags.qps.get() <= 0) {
-    EXIT(1) << "--qps needs to be greater than zero";
+    cerr << flags.usage("--qps needs to be greater than zero") << endl;
+    return EXIT_FAILURE;
   }
 
   // We want the logger to catch failure signals.
@@ -344,7 +331,8 @@ int main(int argc, char** argv)
     cout << "Enabling authentication for the framework" << endl;
 
     if (flags.secret.isNone()) {
-      EXIT(1) << "Expecting --secret when --authenticate is set";
+      cerr << "Expecting --secret when --authenticate is set" << endl;
+      return EXIT_FAILURE;
     }
 
     string secret = flags.secret.get();
@@ -364,7 +352,7 @@ int main(int argc, char** argv)
         &scheduler, framework, flags.master.get());
   }
 
-  int status = driver->run() == DRIVER_STOPPED ? 0 : 1;
+  int status = driver->run() == DRIVER_STOPPED ? EXIT_SUCCESS : EXIT_SUCCESS;
 
   // Ensure that the driver process terminates.
   driver->stop();

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/examples/low_level_scheduler_libprocess.cpp
----------------------------------------------------------------------
diff --git a/src/examples/low_level_scheduler_libprocess.cpp 
b/src/examples/low_level_scheduler_libprocess.cpp
index bee2e7e..bd228fd 100644
--- a/src/examples/low_level_scheduler_libprocess.cpp
+++ b/src/examples/low_level_scheduler_libprocess.cpp
@@ -427,5 +427,5 @@ int main(int argc, char** argv)
   process::wait(scheduler);
   delete scheduler;
 
-  return 0;
+  return EXIT_SUCCESS;
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/examples/low_level_scheduler_pthread.cpp
----------------------------------------------------------------------
diff --git a/src/examples/low_level_scheduler_pthread.cpp 
b/src/examples/low_level_scheduler_pthread.cpp
index fb8cd66..81388f1 100644
--- a/src/examples/low_level_scheduler_pthread.cpp
+++ b/src/examples/low_level_scheduler_pthread.cpp
@@ -483,5 +483,5 @@ int main(int argc, char** argv)
   scheduler->wait();
   delete scheduler;
 
-  return 0;
+  return EXIT_SUCCESS;
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/examples/persistent_volume_framework.cpp
----------------------------------------------------------------------
diff --git a/src/examples/persistent_volume_framework.cpp 
b/src/examples/persistent_volume_framework.cpp
index 8a893fc..6a0c0cb 100644
--- a/src/examples/persistent_volume_framework.cpp
+++ b/src/examples/persistent_volume_framework.cpp
@@ -43,6 +43,7 @@
 using namespace mesos;
 using namespace mesos::internal;
 
+using std::cerr;
 using std::cout;
 using std::endl;
 using std::ostringstream;
@@ -403,11 +404,6 @@ public:
         "tasks_per_shard",
         "The number of tasks should be launched per shard.",
         3);
-
-    add(&help,
-        "help",
-        "Print this help message",
-        false);
   }
 
   Option<string> master;
@@ -415,23 +411,9 @@ public:
   string principal;
   size_t num_shards;
   size_t tasks_per_shard;
-  bool help;
 };
 
 
-static string usage(const char* argv0, const flags::FlagsBase& flags)
-{
-  ostringstream stream;
-
-  stream << "Usage: " << os::basename(argv0).get() << " [...]" << endl
-         << endl
-         << "Supported options:" << endl
-         << flags.usage();
-
-  return stream.str();
-}
-
-
 int main(int argc, char** argv)
 {
   Flags flags;
@@ -439,15 +421,18 @@ int main(int argc, char** argv)
   Try<Nothing> load = flags.load("MESOS_", argc, argv);
 
   if (load.isError()) {
-    EXIT(1) << load.error() << endl << usage(argv[0], flags);
+    cerr << flags.usage(load.error()) << endl;
+    return EXIT_FAILURE;
   }
 
   if (flags.help) {
-    EXIT(1) << usage(argv[0], flags);
+    cout << flags.usage() << endl;
+    return EXIT_SUCCESS;
   }
 
   if (flags.master.isNone()) {
-    EXIT(1) << "Missing required option --master. See --help";
+    cerr << flags.usage("Missing required option --master") << endl;
+    return EXIT_FAILURE;
   }
 
   logging::initialize(argv[0], flags, true); // Catch signals.
@@ -489,7 +474,7 @@ int main(int argc, char** argv)
       framework,
       flags.master.get());
 
-  int status = driver->run() == DRIVER_STOPPED ? 0 : 1;
+  int status = driver->run() == DRIVER_STOPPED ? EXIT_SUCCESS : EXIT_FAILURE;
 
   driver->stop();
   delete driver;

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/health-check/main.cpp
----------------------------------------------------------------------
diff --git a/src/health-check/main.cpp b/src/health-check/main.cpp
index a4ce742..3607479 100644
--- a/src/health-check/main.cpp
+++ b/src/health-check/main.cpp
@@ -294,66 +294,60 @@ int main(int argc, char** argv)
 
   Flags flags;
 
-  bool help;
-  flags.add(&help,
-            "help",
-            "Prints this help message",
-            false);
-
   Try<Nothing> load = flags.load(None(), argc, argv);
 
   if (load.isError()) {
-    LOG(WARNING) << load.error();
-    usage(argv[0], flags);
-    return -1;
+    cerr << flags.usage(load.error()) << endl;
+    return EXIT_FAILURE;
   }
 
-  if (help) {
-    usage(argv[0], flags);
-    return 0;
+  if (flags.help) {
+    cout << flags.usage() << endl;
+    return EXIT_SUCCESS;
   }
 
   if (flags.health_check_json.isNone()) {
-    LOG(WARNING) << "Expected JSON with health check description";
-    usage(argv[0], flags);
-    return 0;
+    cerr << flags.usage("Expected JSON with health check description") << endl;
+    return EXIT_FAILURE;
   }
 
   Try<JSON::Object> parse =
     JSON::parse<JSON::Object>(flags.health_check_json.get());
-  if (parse.isError()) {
-    LOG(WARNING) << "JSON parse error: " << parse.error();
-    usage(argv[0], flags);
-    return 0;
-  }
 
-  if (flags.executor.isNone()) {
-    LOG(WARNING) << "Expected UPID for health check";
-    usage(argv[0], flags);
-    return 0;
+  if (parse.isError()) {
+    cerr << flags.usage("Failed to parse --health_check_json: " + 
parse.error())
+         << endl;
+    return EXIT_FAILURE;
   }
 
   Try<HealthCheck> check = protobuf::parse<HealthCheck>(parse.get());
+
   if (check.isError()) {
-    LOG(WARNING) << "JSON error: " << check.error();
-    usage(argv[0], flags);
-    return 0;
+    cerr << flags.usage("Failed to parse --health_check_json: " + 
check.error())
+         << endl;
+    return EXIT_SUCCESS;
+  }
+
+  if (flags.executor.isNone()) {
+    cerr << flags.usage("Missing required option --executor") << endl;
+    return EXIT_FAILURE;
   }
 
   if (check.get().has_http() && check.get().has_command()) {
-    LOG(WARNING) << "Both HTTP and Command check passed in";
-    return -1;
+    cerr << flags.usage("Both 'http' and 'command' health check requested")
+         << endl;
+    return EXIT_FAILURE;
   }
 
   if (!check.get().has_http() && !check.get().has_command()) {
-    LOG(WARNING) << "No health check found";
-    return -1;
+    cerr << flags.usage("Expecting one of 'http' or 'command' health check")
+         << endl;
+    return EXIT_FAILURE;
   }
 
   if (flags.task_id.isNone()) {
-    LOG(WARNING) << "TaskID error: " << check.error();
-    usage(argv[0], flags);
-    return 0;
+    cerr << flags.usage("Missing required option --task_id") << endl;
+    return EXIT_FAILURE;
   }
 
   TaskID taskID;
@@ -377,8 +371,8 @@ int main(int argc, char** argv)
 
   if (checking.isFailed()) {
     LOG(WARNING) << "Health check failed " << checking.failure();
-    return 1;
+    return EXIT_FAILURE;
   }
 
-  return 0;
+  return EXIT_SUCCESS;
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/launcher/executor.cpp
----------------------------------------------------------------------
diff --git a/src/launcher/executor.cpp b/src/launcher/executor.cpp
index de6f1b1..f79dc60 100644
--- a/src/launcher/executor.cpp
+++ b/src/launcher/executor.cpp
@@ -581,15 +581,6 @@ private:
 } // namespace mesos {
 
 
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
-  cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
-       << endl
-       << "Supported options:" << endl
-       << flags.usage();
-}
-
-
 class Flags : public flags::FlagsBase
 {
 public:
@@ -615,24 +606,17 @@ int main(int argc, char** argv)
 {
   Flags flags;
 
-  bool help;
-  flags.add(&help,
-            "help",
-            "Prints this help message",
-            false);
-
   // Load flags from command line.
   Try<Nothing> load = flags.load(None(), &argc, &argv);
 
   if (load.isError()) {
-    cerr << load.error() << endl;
-    usage(argv[0], flags);
-    return -1;
+    cerr << flags.usage(load.error()) << endl;
+    return EXIT_FAILURE;
   }
 
-  if (help) {
-    usage(argv[0], flags);
-    return -1;
+  if (flags.help) {
+    cout << flags.usage() << endl;
+    return EXIT_SUCCESS;
   }
 
   // After flags.load(..., &argc, &argv) all flags will have been
@@ -653,5 +637,5 @@ int main(int argc, char** argv)
   }
   mesos::internal::CommandExecutor executor(override, path);
   mesos::MesosExecutorDriver driver(&executor);
-  return driver.run() == mesos::DRIVER_STOPPED ? 0 : 1;
+  return driver.run() == mesos::DRIVER_STOPPED ? EXIT_SUCCESS : EXIT_FAILURE;
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/local/main.cpp
----------------------------------------------------------------------
diff --git a/src/local/main.cpp b/src/local/main.cpp
index a641b9e..ec21ed0 100644
--- a/src/local/main.cpp
+++ b/src/local/main.cpp
@@ -39,21 +39,11 @@ using mesos::internal::master::Master;
 using mesos::internal::slave::Slave;
 
 using std::cerr;
+using std::cout;
 using std::endl;
 using std::string;
 
 
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
-  cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
-       << endl
-       << "Launches an in-memory cluster within a single process."
-       << endl
-       << "Supported options:" << endl
-       << flags.usage();
-}
-
-
 int main(int argc, char **argv)
 {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
@@ -64,6 +54,10 @@ int main(int argc, char **argv)
   // master::flags, then slave::Flags, then local::Flags.
   local::Flags flags;
 
+  flags.setUsageMessage(
+      "Usage: " + os::basename(argv[0]).get() + " [...]\n\n" +
+      "Launches an in-memory cluster within a single process.");
+
   // The following flags are executable specific (e.g., since we only
   // have one instance of libprocess per execution, we only want to
   // advertise the port and ip option once, here).
@@ -73,25 +67,18 @@ int main(int argc, char **argv)
   Option<string> ip;
   flags.add(&ip, "ip", "IP address to listen on");
 
-  bool help;
-  flags.add(&help,
-            "help",
-            "Prints this help message",
-            false);
-
   // Load flags from environment and command line but allow unknown
   // flags since we might have some master/slave flags as well.
   Try<Nothing> load = flags.load("MESOS_", argc, argv, true);
 
   if (load.isError()) {
-    cerr << load.error() << endl;
-    usage(argv[0], flags);
-    exit(1);
+    cerr << flags.usage(load.error()) << endl;
+    return EXIT_FAILURE;
   }
 
-  if (help) {
-    usage(argv[0], flags);
-    exit(1);
+  if (flags.help) {
+    cout << flags.usage() << endl;
+    return EXIT_SUCCESS;
   }
 
   // Initialize libprocess.
@@ -107,5 +94,5 @@ int main(int argc, char **argv)
 
   process::wait(local::launch(flags));
 
-  return 0;
+  return EXIT_SUCCESS;
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/benchmark.cpp
----------------------------------------------------------------------
diff --git a/src/log/tool/benchmark.cpp b/src/log/tool/benchmark.cpp
index 01e5511..4895dd8 100644
--- a/src/log/tool/benchmark.cpp
+++ b/src/log/tool/benchmark.cpp
@@ -47,7 +47,6 @@ using std::cout;
 using std::endl;
 using std::ifstream;
 using std::ofstream;
-using std::ostringstream;
 using std::string;
 using std::vector;
 
@@ -95,44 +94,30 @@ Benchmark::Flags::Flags()
       "initialize",
       "Whether to initialize the log",
       true);
-
-  add(&Flags::help,
-      "help",
-      "Prints the help message",
-      false);
-}
-
-
-string Benchmark::usage(const string& argv0) const
-{
-  ostringstream out;
-
-  out << "Usage: " << argv0 << " " << name() << " [OPTIONS]" << endl
-      << endl
-      << "This command is used to do performance test on the" << endl
-      << "replicated log. It takes a trace file of write sizes" << endl
-      << "and replay that trace to measure the latency of each" << endl
-      << "write. The data to be written for each write can be" << endl
-      << "specified using the '--type' flag." << endl
-      << endl
-      << "Supported OPTIONS:" << endl
-      << flags.usage();
-
-  return out.str();
 }
 
 
 Try<Nothing> Benchmark::execute(int argc, char** argv)
 {
+  flags.setUsageMessage(
+      "Usage: " + name() + " [options]\n"
+      "\n"
+      "This command is used to do performance test on the\n"
+      "replicated log. It takes a trace file of write sizes\n"
+      "and replay that trace to measure the latency of each\n"
+      "write. The data to be written for each write can be\n"
+      "specified using the --type flag.\n"
+      "\n");
+
   // Configure the tool by parsing command line arguments.
   if (argc > 0 && argv != NULL) {
     Try<Nothing> load = flags.load(None(), argc, argv);
     if (load.isError()) {
-      return Error(load.error() + "\n\n" + usage(argv[0]));
+      return Error(flags.usage(load.error()));
     }
 
     if (flags.help) {
-      return Error(usage(argv[0]));
+      return Error(flags.usage());
     }
 
     process::initialize();
@@ -140,27 +125,27 @@ Try<Nothing> Benchmark::execute(int argc, char** argv)
   }
 
   if (flags.quorum.isNone()) {
-    return Error("Missing flag '--quorum'");
+    return Error(flags.usage("Missing required option --quorum"));
   }
 
   if (flags.path.isNone()) {
-    return Error("Missing flag '--path'");
+    return Error(flags.usage("Missing required option --path"));
   }
 
   if (flags.servers.isNone()) {
-    return Error("Missing flag '--servers'");
+    return Error(flags.usage("Missing required option --servers"));
   }
 
   if (flags.znode.isNone()) {
-    return Error("Missing flag '--znode'");
+    return Error(flags.usage("Missing required option --znode"));
   }
 
   if (flags.input.isNone()) {
-    return Error("Missing flag '--input'");
+    return Error(flags.usage("Missing required option --input"));
   }
 
   if (flags.output.isNone()) {
-    return Error("Missing flag '--output'");
+    return Error(flags.usage("Missing required option --output"));
   }
 
   // Initialize the log.

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/benchmark.hpp
----------------------------------------------------------------------
diff --git a/src/log/tool/benchmark.hpp b/src/log/tool/benchmark.hpp
index e0109e2..5714b87 100644
--- a/src/log/tool/benchmark.hpp
+++ b/src/log/tool/benchmark.hpp
@@ -55,9 +55,6 @@ public:
 
   // Users can change the default configuration by setting this flags.
   Flags flags;
-
-private:
-  std::string usage(const std::string& argv0) const;
 };
 
 } // namespace tool {

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/initialize.cpp
----------------------------------------------------------------------
diff --git a/src/log/tool/initialize.cpp b/src/log/tool/initialize.cpp
index ccda7fb..a5146fd 100644
--- a/src/log/tool/initialize.cpp
+++ b/src/log/tool/initialize.cpp
@@ -16,9 +16,6 @@
  * limitations under the License.
  */
 
-#include <iostream>
-#include <sstream>
-
 #include <process/process.hpp>
 #include <process/timeout.hpp>
 
@@ -31,8 +28,6 @@
 
 using namespace process;
 
-using std::endl;
-using std::ostringstream;
 using std::string;
 
 namespace mesos {
@@ -50,40 +45,26 @@ Initialize::Flags::Flags()
       "timeout",
       "Maximum time allowed for the command to finish\n"
       "(e.g., 500ms, 1sec, etc.)");
-
-  add(&Flags::help,
-      "help",
-      "Prints the help message",
-      false);
-}
-
-
-string Initialize::usage(const string& argv0) const
-{
-  ostringstream out;
-
-  out << "Usage: " << argv0 << " " << name() << " [OPTIONS]" << endl
-      << endl
-      << "This command is used to initialize the log" << endl
-      << endl
-      << "Supported OPTIONS:" << endl
-      << flags.usage();
-
-  return out.str();
 }
 
 
 Try<Nothing> Initialize::execute(int argc, char** argv)
 {
+  flags.setUsageMessage(
+      "Usage: " + name() + " [option]\n"
+      "\n"
+      "This command is used to initialize the log.\n"
+      "\n");
+
   // Configure the tool by parsing command line arguments.
   if (argc > 0 && argv != NULL) {
     Try<Nothing> load = flags.load(None(), argc, argv);
     if (load.isError()) {
-      return Error(load.error() + "\n\n" + usage(argv[0]));
+      return Error(flags.usage(load.error()));
     }
 
     if (flags.help) {
-      return Error(usage(argv[0]));
+      return Error(flags.usage());
     }
 
     process::initialize();
@@ -91,7 +72,7 @@ Try<Nothing> Initialize::execute(int argc, char** argv)
   }
 
   if (flags.path.isNone()) {
-    return Error("Missing flag: '--path'");
+    return Error(flags.usage("Missing required option --path"));
   }
 
   // Setup the timeout if specified.

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/initialize.hpp
----------------------------------------------------------------------
diff --git a/src/log/tool/initialize.hpp b/src/log/tool/initialize.hpp
index 10ac269..dc25e97 100644
--- a/src/log/tool/initialize.hpp
+++ b/src/log/tool/initialize.hpp
@@ -50,9 +50,6 @@ public:
 
   // Users can change the default configuration by setting this flags.
   Flags flags;
-
-private:
-  std::string usage(const std::string& argv0) const;
 };
 
 } // namespace tool {

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/read.cpp
----------------------------------------------------------------------
diff --git a/src/log/tool/read.cpp b/src/log/tool/read.cpp
index d141385..08d1932 100644
--- a/src/log/tool/read.cpp
+++ b/src/log/tool/read.cpp
@@ -19,12 +19,12 @@
 #include <stdint.h>
 
 #include <iostream>
-#include <sstream>
 
 #include <process/process.hpp>
 #include <process/timeout.hpp>
 
 #include <stout/error.hpp>
+#include <stout/stringify.hpp>
 
 #include "log/replica.hpp"
 #include "log/tool/read.hpp"
@@ -36,7 +36,6 @@ using namespace process;
 using std::cout;
 using std::endl;
 using std::list;
-using std::ostringstream;
 using std::string;
 
 namespace mesos {
@@ -62,40 +61,26 @@ Read::Flags::Flags()
       "timeout",
       "Maximum time allowed for the command to finish\n"
       "(e.g., 500ms, 1sec, etc.)");
-
-  add(&Flags::help,
-      "help",
-      "Prints the help message",
-      false);
-}
-
-
-string Read::usage(const string& argv0) const
-{
-  ostringstream out;
-
-  out << "Usage: " << argv0 << " " << name() << " [OPTIONS]" << endl
-      << endl
-      << "This command is used to read the log" << endl
-      << endl
-      << "Supported OPTIONS:" << endl
-      << flags.usage();
-
-  return out.str();
 }
 
 
 Try<Nothing> Read::execute(int argc, char** argv)
 {
+  flags.setUsageMessage(
+      "Usage: " + name() + " [options]\n"
+      "\n"
+      "This command is used to read the log.\n"
+      "\n");
+
   // Configure the tool by parsing command line arguments.
   if (argc > 0 && argv != NULL) {
     Try<Nothing> load = flags.load(None(), argc, argv);
     if (load.isError()) {
-      return Error(load.error() + "\n\n" + usage(argv[0]));
+      return Error(flags.usage(load.error()));
     }
 
     if (flags.help) {
-      return Error(usage(argv[0]));
+      return Error(flags.usage());
     }
 
     process::initialize();
@@ -103,7 +88,7 @@ Try<Nothing> Read::execute(int argc, char** argv)
   }
 
   if (flags.path.isNone()) {
-    return Error("Missing flag '--path'");
+    return Error(flags.usage("Missing required flag --path"));
   }
 
   // Setup the timeout if specified.

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/read.hpp
----------------------------------------------------------------------
diff --git a/src/log/tool/read.hpp b/src/log/tool/read.hpp
index 9a6971b..f5958cd 100644
--- a/src/log/tool/read.hpp
+++ b/src/log/tool/read.hpp
@@ -54,9 +54,6 @@ public:
 
   // Users can change the default configuration by setting this flags.
   Flags flags;
-
-private:
-  std::string usage(const std::string& argv0) const;
 };
 
 } // namespace tool {

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/replica.cpp
----------------------------------------------------------------------
diff --git a/src/log/tool/replica.cpp b/src/log/tool/replica.cpp
index 3985fc7..1eba480 100644
--- a/src/log/tool/replica.cpp
+++ b/src/log/tool/replica.cpp
@@ -17,7 +17,6 @@
  */
 
 #include <iostream>
-#include <sstream>
 
 #include <process/future.hpp>
 #include <process/process.hpp>
@@ -33,7 +32,6 @@
 using namespace process;
 
 using std::endl;
-using std::ostringstream;
 using std::string;
 
 namespace mesos {
@@ -63,40 +61,26 @@ Replica::Flags::Flags()
       "initialize",
       "Whether to initialize the log",
       true);
-
-  add(&Flags::help,
-      "help",
-      "Prints the help message",
-      false);
-}
-
-
-string Replica::usage(const string& argv0) const
-{
-  ostringstream out;
-
-  out << "Usage: " << argv0 << " " << name() << " [OPTIONS]" << endl
-      << endl
-      << "This command is used to start a replica server" << endl
-      << endl
-      << "Supported OPTIONS:" << endl
-      << flags.usage();
-
-  return out.str();
 }
 
 
 Try<Nothing> Replica::execute(int argc, char** argv)
 {
+  flags.setUsageMessage(
+      "Usage: " + name() + " [options]\n"
+      "\n"
+      "This command is used to start a replica server.\n"
+      "\n");
+
   // Configure the tool by parsing command line arguments.
   if (argc > 0 && argv != NULL) {
     Try<Nothing> load = flags.load(None(), argc, argv);
     if (load.isError()) {
-      return Error(load.error() + "\n\n" + usage(argv[0]));
+      return Error(flags.usage(load.error()));
     }
 
     if (flags.help) {
-      return Error(usage(argv[0]));
+      return Error(flags.usage());
     }
 
     process::initialize();
@@ -104,19 +88,19 @@ Try<Nothing> Replica::execute(int argc, char** argv)
   }
 
   if (flags.quorum.isNone()) {
-    return Error("Missing flag '--quorum'");
+    return Error(flags.usage("Missing required option --quorum"));
   }
 
   if (flags.path.isNone()) {
-    return Error("Missing flag '--path'");
+    return Error(flags.usage("Missing required option --path"));
   }
 
   if (flags.servers.isNone()) {
-    return Error("Missing flag '--servers'");
+    return Error(flags.usage("Missing required option --servers"));
   }
 
   if (flags.znode.isNone()) {
-    return Error("Missing flag '--znode'");
+    return Error(flags.usage("Missing required option --znode"));
   }
 
   // Initialize the log.

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/replica.hpp
----------------------------------------------------------------------
diff --git a/src/log/tool/replica.hpp b/src/log/tool/replica.hpp
index 7140c7e..7a8f391 100644
--- a/src/log/tool/replica.hpp
+++ b/src/log/tool/replica.hpp
@@ -55,9 +55,6 @@ public:
 
   // Users can change the default configuration by setting this flags.
   Flags flags;
-
-private:
-  std::string usage(const std::string& argv0) const;
 };
 
 } // namespace tool {

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/master/main.cpp
----------------------------------------------------------------------
diff --git a/src/master/main.cpp b/src/master/main.cpp
index d5666bc..3d490c3 100644
--- a/src/master/main.cpp
+++ b/src/master/main.cpp
@@ -98,15 +98,6 @@ using std::string;
 using std::vector;
 
 
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
-  cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
-       << endl
-       << "Supported options:" << endl
-       << flags.usage();
-}
-
-
 void version()
 {
   cout << "mesos" << " " << MESOS_VERSION << endl;
@@ -137,28 +128,21 @@ int main(int argc, char** argv)
             "  zk://username:password@host1:port1,host2:port2,.../path\n"
             "  file:///path/to/file (where file contains one of the above)");
 
-  bool help;
-  flags.add(&help,
-            "help",
-            "Prints this help message",
-            false);
-
   Try<Nothing> load = flags.load("MESOS_", argc, argv);
 
   if (load.isError()) {
-    cerr << load.error() << endl;
-    usage(argv[0], flags);
-    exit(1);
+    cerr << flags.usage(load.error()) << endl;
+    return EXIT_FAILURE;
   }
 
   if (flags.version) {
     version();
-    exit(0);
+    return EXIT_SUCCESS;
   }
 
-  if (help) {
-    usage(argv[0], flags);
-    exit(1);
+  if (flags.help) {
+    cout << flags.usage() << endl;
+    return EXIT_SUCCESS;
   }
 
   // Initialize modules. Note that since other subsystems may depend
@@ -166,7 +150,7 @@ int main(int argc, char** argv)
   if (flags.modules.isSome()) {
     Try<Nothing> result = ModuleManager::load(flags.modules.get());
     if (result.isError()) {
-      EXIT(1) << "Error loading modules: " << result.error();
+      EXIT(EXIT_FAILURE) << "Error loading modules: " << result.error();
     }
   }
 
@@ -174,7 +158,7 @@ int main(int argc, char** argv)
   if (flags.hooks.isSome()) {
     Try<Nothing> result = HookManager::initialize(flags.hooks.get());
     if (result.isError()) {
-      EXIT(1) << "Error installing hooks: " << result.error();
+      EXIT(EXIT_FAILURE) << "Error installing hooks: " << result.error();
     }
   }
 
@@ -206,8 +190,9 @@ int main(int argc, char** argv)
   Try<Allocator*> allocator = Allocator::create(allocatorName);
 
   if (allocator.isError()) {
-    EXIT(1) << "Failed to create '" << allocatorName << "' allocator: "
-            << allocator.error();
+    EXIT(EXIT_FAILURE)
+      << "Failed to create '" << allocatorName
+      << "' allocator: " << allocator.error();
   }
 
   CHECK_NOTNULL(allocator.get());
@@ -218,8 +203,9 @@ int main(int argc, char** argv)
 
   if (flags.registry == "in_memory") {
     if (flags.registry_strict) {
-      EXIT(1) << "Cannot use '--registry_strict' when using in-memory storage"
-              << " based registry";
+      EXIT(EXIT_FAILURE)
+        << "Cannot use '--registry_strict' when using in-memory storage"
+        << " based registry";
     }
     storage = new state::InMemoryStorage();
   } else if (flags.registry == "replicated_log" ||
@@ -227,25 +213,28 @@ int main(int argc, char** argv)
     // TODO(bmahler): "log_storage" is present for backwards
     // compatibility, can be removed before 0.19.0.
     if (flags.work_dir.isNone()) {
-      EXIT(1) << "--work_dir needed for replicated log based registry";
+      EXIT(EXIT_FAILURE)
+        << "--work_dir needed for replicated log based registry";
     }
 
     Try<Nothing> mkdir = os::mkdir(flags.work_dir.get());
     if (mkdir.isError()) {
-      EXIT(1) << "Failed to create work directory '" << flags.work_dir.get()
-              << "': " << mkdir.error();
+      EXIT(EXIT_FAILURE)
+        << "Failed to create work directory '" << flags.work_dir.get()
+        << "': " << mkdir.error();
     }
 
     if (zk.isSome()) {
       // Use replicated log with ZooKeeper.
       if (flags.quorum.isNone()) {
-        EXIT(1) << "Need to specify --quorum for replicated log based"
-                << " registry when using ZooKeeper";
+        EXIT(EXIT_FAILURE)
+          << "Need to specify --quorum for replicated log based"
+          << " registry when using ZooKeeper";
       }
 
       Try<zookeeper::URL> url = zookeeper::URL::parse(zk.get());
       if (url.isError()) {
-        EXIT(1) << "Error parsing ZooKeeper URL: " << url.error();
+        EXIT(EXIT_FAILURE) << "Error parsing ZooKeeper URL: " << url.error();
       }
 
       log = new Log(
@@ -266,8 +255,9 @@ int main(int argc, char** argv)
     }
     storage = new state::LogStorage(log);
   } else {
-    EXIT(1) << "'" << flags.registry << "' is not a supported"
-            << " option for registry persistence";
+    EXIT(EXIT_FAILURE)
+      << "'" << flags.registry << "' is not a supported"
+      << " option for registry persistence";
   }
 
   CHECK_NOTNULL(storage);
@@ -285,7 +275,8 @@ int main(int argc, char** argv)
   // Option<string>.
   Try<MasterContender*> contender_ = MasterContender::create(zk.get(""));
   if (contender_.isError()) {
-    EXIT(1) << "Failed to create a master contender: " << contender_.error();
+    EXIT(EXIT_FAILURE)
+      << "Failed to create a master contender: " << contender_.error();
   }
   contender = contender_.get();
 
@@ -293,7 +284,8 @@ int main(int argc, char** argv)
   // Option<string>.
   Try<MasterDetector*> detector_ = MasterDetector::create(zk.get(""));
   if (detector_.isError()) {
-    EXIT(1) << "Failed to create a master detector: " << detector_.error();
+    EXIT(EXIT_FAILURE)
+      << "Failed to create a master detector: " << detector_.error();
   }
   detector = detector_.get();
 
@@ -302,8 +294,9 @@ int main(int argc, char** argv)
     Try<Owned<Authorizer>> create = Authorizer::create(flags.acls.get());
 
     if (create.isError()) {
-      EXIT(1) << "Failed to initialize the authorizer: "
-              << create.error() << " (see --acls flag)";
+      EXIT(EXIT_FAILURE)
+        << "Failed to initialize the authorizer: "
+        << create.error() << " (see --acls flag)";
     }
 
     // Now pull out the authorizer but need to make a copy since we
@@ -320,25 +313,28 @@ int main(int argc, char** argv)
       strings::tokenize(flags.slave_removal_rate_limit.get(), "/");
 
     if (tokens.size() != 2) {
-      EXIT(1) << "Invalid slave_removal_rate_limit: "
-              << flags.slave_removal_rate_limit.get()
-              << ". Format is <Number of slaves>/<Duration>";
+      EXIT(EXIT_FAILURE)
+        << "Invalid slave_removal_rate_limit: "
+        << flags.slave_removal_rate_limit.get()
+        << ". Format is <Number of slaves>/<Duration>";
     }
 
     Try<int> permits = numify<int>(tokens[0]);
     if (permits.isError()) {
-      EXIT(1) << "Invalid slave_removal_rate_limit: "
-              << flags.slave_removal_rate_limit.get()
-              << ". Format is <Number of slaves>/<Duration>"
-              << ": " << permits.error();
+      EXIT(EXIT_FAILURE)
+        << "Invalid slave_removal_rate_limit: "
+        << flags.slave_removal_rate_limit.get()
+        << ". Format is <Number of slaves>/<Duration>"
+        << ": " << permits.error();
     }
 
     Try<Duration> duration = Duration::parse(tokens[1]);
     if (duration.isError()) {
-      EXIT(1) << "Invalid slave_removal_rate_limit: "
-              << flags.slave_removal_rate_limit.get()
-              << ". Format is <Number of slaves>/<Duration>"
-              << ": " << duration.error();
+      EXIT(EXIT_FAILURE)
+        << "Invalid slave_removal_rate_limit: "
+        << flags.slave_removal_rate_limit.get()
+        << ". Format is <Number of slaves>/<Duration>"
+        << ": " << duration.error();
     }
 
     slaveRemovalLimiter = new RateLimiter(permits.get(), duration.get());
@@ -348,7 +344,8 @@ int main(int argc, char** argv)
   foreach (const string& name, ModuleManager::find<Anonymous>()) {
     Try<Anonymous*> create = ModuleManager::create<Anonymous>(name);
     if (create.isError()) {
-      EXIT(1) << "Failed to create anonymous module named '" << name << "'";
+      EXIT(EXIT_FAILURE)
+        << "Failed to create anonymous module named '" << name << "'";
     }
 
     // We don't bother keeping around the pointer to this anonymous
@@ -399,5 +396,5 @@ int main(int argc, char** argv)
     delete authorizer.get();
   }
 
-  return 0;
+  return EXIT_SUCCESS;
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/slave/containerizer/isolators/network/port_mapping.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/network/port_mapping.cpp 
b/src/slave/containerizer/isolators/network/port_mapping.cpp
index d3c1918..781c35b 100644
--- a/src/slave/containerizer/isolators/network/port_mapping.cpp
+++ b/src/slave/containerizer/isolators/network/port_mapping.cpp
@@ -312,11 +312,6 @@ const char* PortMappingUpdate::NAME = "update";
 
 PortMappingUpdate::Flags::Flags()
 {
-  add(&help,
-      "help",
-      "Prints this help message",
-      false);
-
   add(&eth0_name,
       "eth0_name",
       "The name of the public network interface (e.g., eth0)");
@@ -581,11 +576,6 @@ const char* PortMappingStatistics::NAME = "statistics";
 
 PortMappingStatistics::Flags::Flags()
 {
-  add(&help,
-      "help",
-      "Prints this help message",
-      false);
-
   add(&pid,
       "pid",
       "The pid of the process whose namespaces we will enter");

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/slave/containerizer/isolators/network/port_mapping.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/network/port_mapping.hpp 
b/src/slave/containerizer/isolators/network/port_mapping.hpp
index 52c7e7c..9f83af1 100644
--- a/src/slave/containerizer/isolators/network/port_mapping.hpp
+++ b/src/slave/containerizer/isolators/network/port_mapping.hpp
@@ -342,7 +342,6 @@ public:
   {
     Flags();
 
-    bool help;
     Option<std::string> eth0_name;
     Option<std::string> lo_name;
     Option<pid_t> pid;
@@ -372,7 +371,6 @@ public:
   {
     Flags();
 
-    bool help;
     Option<pid_t> pid;
     bool enable_socket_statistics_summary;
     bool enable_socket_statistics_details;

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/slave/main.cpp
----------------------------------------------------------------------
diff --git a/src/slave/main.cpp b/src/slave/main.cpp
index f762f5b..e3a45f4 100644
--- a/src/slave/main.cpp
+++ b/src/slave/main.cpp
@@ -62,15 +62,6 @@ using std::endl;
 using std::string;
 
 
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
-  cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
-       << endl
-       << "Supported options:" << endl
-       << flags.usage();
-}
-
-
 void version()
 {
   cout << "mesos" << " " << MESOS_VERSION << endl;
@@ -100,32 +91,28 @@ int main(int argc, char** argv)
             "  zk://username:password@host1:port1,host2:port2,.../path\n"
             "  file:///path/to/file (where file contains one of the above)");
 
-  bool help;
-  flags.add(&help,
-            "help",
-            "Prints this help message",
-            false);
-
   Try<Nothing> load = flags.load("MESOS_", argc, argv);
 
+  // TODO(marco): this pattern too should be abstracted away
+  // in FlagsBase; I have seen it at least 15 times.
   if (load.isError()) {
-    cerr << load.error() << endl;
-    usage(argv[0], flags);
-    EXIT(1);
+    cerr << flags.usage(load.error()) << endl;
+    return EXIT_FAILURE;
   }
 
-  if (help) {
-    usage(argv[0], flags);
-    EXIT(1);
+  if (flags.help) {
+    cout << flags.usage() << endl;
+    return EXIT_SUCCESS;
   }
 
   if (flags.version) {
     version();
-    exit(0);
+    return EXIT_SUCCESS;
   }
 
   if (master.isNone()) {
-    EXIT(1) << "Missing required option --master";
+    cerr << flags.usage("Missing required option --master") << endl;
+    return EXIT_FAILURE;
   }
 
   // Initialize modules. Note that since other subsystems may depend
@@ -133,7 +120,7 @@ int main(int argc, char** argv)
   if (flags.modules.isSome()) {
     Try<Nothing> result = ModuleManager::load(flags.modules.get());
     if (result.isError()) {
-      EXIT(1) << "Error loading modules: " << result.error();
+      EXIT(EXIT_FAILURE) << "Error loading modules: " << result.error();
     }
   }
 
@@ -141,7 +128,7 @@ int main(int argc, char** argv)
   if (flags.hooks.isSome()) {
     Try<Nothing> result = HookManager::initialize(flags.hooks.get());
     if (result.isError()) {
-      EXIT(1) << "Error installing hooks: " << result.error();
+      EXIT(EXIT_FAILURE) << "Error installing hooks: " << result.error();
     }
   }
 
@@ -174,21 +161,23 @@ int main(int argc, char** argv)
     Containerizer::create(flags, false, &fetcher);
 
   if (containerizer.isError()) {
-    EXIT(1) << "Failed to create a containerizer: "
-            << containerizer.error();
+    EXIT(EXIT_FAILURE)
+      << "Failed to create a containerizer: " << containerizer.error();
   }
 
   Try<MasterDetector*> detector = MasterDetector::create(master.get());
 
   if (detector.isError()) {
-    EXIT(1) << "Failed to create a master detector: " << detector.error();
+    EXIT(EXIT_FAILURE)
+      << "Failed to create a master detector: " << detector.error();
   }
 
   // Create anonymous modules.
   foreach (const string& name, ModuleManager::find<Anonymous>()) {
     Try<Anonymous*> create = ModuleManager::create<Anonymous>(name);
     if (create.isError()) {
-      EXIT(1) << "Failed to create anonymous module named '" << name << "'";
+      EXIT(EXIT_FAILURE)
+        << "Failed to create anonymous module named '" << name << "'";
     }
 
     // We don't bother keeping around the pointer to this anonymous
@@ -200,8 +189,6 @@ int main(int argc, char** argv)
     // terminating.
   }
 
-  LOG(INFO) << "Starting Mesos slave";
-
   Files files;
   GarbageCollector gc;
   StatusUpdateManager statusUpdateManager(flags);
@@ -210,10 +197,13 @@ int main(int argc, char** argv)
     ResourceEstimator::create(flags.resource_estimator);
 
   if (resourceEstimator.isError()) {
-    EXIT(1) << "Failed to create resource estimator: "
-            << resourceEstimator.error();
+    cerr << "Failed to create resource estimator: "
+         << resourceEstimator.error() << endl;
+    return EXIT_FAILURE;
   }
 
+  LOG(INFO) << "Starting Mesos slave";
+
   Slave* slave = new Slave(
       flags,
       detector.get(),
@@ -234,5 +224,5 @@ int main(int argc, char** argv)
 
   delete containerizer.get();
 
-  return 0;
+  return EXIT_SUCCESS;
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/tests/main.cpp
----------------------------------------------------------------------
diff --git a/src/tests/main.cpp b/src/tests/main.cpp
index e3fff5d..970a8b0 100644
--- a/src/tests/main.cpp
+++ b/src/tests/main.cpp
@@ -43,52 +43,37 @@ using namespace mesos::internal;
 using namespace mesos::internal::tests;
 
 using std::cerr;
+using std::cout;
 using std::endl;
 using std::string;
 
 
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
-  cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
-       << endl
-       << "Supported options:" << endl
-       << flags.usage();
-}
-
-
 int main(int argc, char** argv)
 {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   using mesos::internal::tests::flags; // Needed to disabmiguate.
 
-  bool help;
-  flags.add(&help,
-            "help",
-            "Prints this help message",
-            false);
-
   // Load flags from environment and command line but allow unknown
   // flags (since we might have gtest/gmock flags as well).
   Try<Nothing> load = flags.load("MESOS_", argc, argv, true);
 
   if (load.isError()) {
-    cerr << load.error() << endl;
-    usage(argv[0], flags);
-    exit(1);
+    cerr << flags.usage(load.error()) << endl;
+    return EXIT_FAILURE;
   }
 
-  if (help) {
-    usage(argv[0], flags);
-    cerr << endl;
+  if (flags.help) {
+    cout << flags.usage() << endl;
     testing::InitGoogleTest(&argc, argv); // Get usage from gtest too.
-    exit(1);
+    return EXIT_SUCCESS;
   }
 
   // Initialize Modules.
   Try<Nothing> result = tests::initModules(flags.modules);
   if (result.isError()) {
-    EXIT(1) << "Error initializing modules: " << result.error();
+    cerr << "Error initializing modules: " << result.error() << endl;
+    return EXIT_FAILURE;
   }
 
   // Initialize libprocess.
@@ -114,8 +99,8 @@ int main(int argc, char** argv)
   testing::InitGoogleTest(&argc, argv);
   testing::FLAGS_gtest_death_test_style = "threadsafe";
 
-  std::cout << "Source directory: " << flags.source_dir << std::endl;
-  std::cout << "Build directory: " << flags.build_dir << std::endl;
+  cout << "Source directory: " << flags.source_dir << endl;
+  cout << "Build directory: " << flags.build_dir << endl;
 
   // Instantiate our environment. Note that it will be managed by
   // gtest after we add it via testing::AddGlobalTestEnvironment.

http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/usage/main.cpp
----------------------------------------------------------------------
diff --git a/src/usage/main.cpp b/src/usage/main.cpp
index 97f55e9..86fd796 100644
--- a/src/usage/main.cpp
+++ b/src/usage/main.cpp
@@ -60,62 +60,45 @@ public:
 };
 
 
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
-  cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
-       << endl
-       << "Supported options:" << endl
-       << flags.usage();
-}
-
-
 int main(int argc, char** argv)
 {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   Flags flags;
 
-  bool help;
-  flags.add(&help,
-            "help",
-            "Prints this help message",
-            false);
-
   Try<Nothing> load = flags.load(None(), argc, argv);
 
   if (load.isError()) {
-    cerr << load.error() << endl;
-    usage(argv[0], flags);
-    return -1;
+    cerr << flags.usage(load.error()) << endl;
+    return EXIT_FAILURE;
   }
 
-  if (help) {
-    usage(argv[0], flags);
-    return 0;
+  if (flags.help) {
+    cout << flags.usage() << endl;
+    return EXIT_SUCCESS;
   }
 
   if (flags.pid.isNone()) {
-    cerr << "Missing pid" << endl;
-    usage(argv[0], flags);
-    return -1;
+    cerr << flags.usage("Missing required option --pid") << endl;
+    return EXIT_FAILURE;
   }
 
   Try<ResourceStatistics> statistics = mesos::internal::usage(flags.pid.get());
 
   if (statistics.isError()) {
     cerr << "Failed to get usage: " << statistics.error() << endl;
-    return -1;
+    return EXIT_FAILURE;
   }
 
   if (flags.recordio) {
     Try<Nothing> write = protobuf::write(STDOUT_FILENO, statistics.get());
     if (write.isError()) {
       cerr << "Failed to write record: " << write.error() << endl;
-      return -1;
+      return EXIT_FAILURE;
     }
   } else {
     cout << stringify(JSON::Protobuf(statistics.get())) << endl;
   }
 
-  return 0;
+  return EXIT_SUCCESS;
 }

Reply via email to