diff options
-rwxr-xr-x | qa/workunits/cephtool/test.sh | 2 | ||||
-rw-r--r-- | src/common/ceph_argparse.cc | 54 | ||||
-rw-r--r-- | src/common/ceph_argparse.h | 3 | ||||
-rw-r--r-- | src/common/config.cc | 8 | ||||
-rw-r--r-- | src/test/ceph_argparse.cc | 9 |
5 files changed, 57 insertions, 19 deletions
diff --git a/qa/workunits/cephtool/test.sh b/qa/workunits/cephtool/test.sh index 64663fcd702..595fa1a9fa9 100755 --- a/qa/workunits/cephtool/test.sh +++ b/qa/workunits/cephtool/test.sh @@ -204,6 +204,8 @@ function test_mon_injectargs() check_response "osd_debug_op_order = 'true'" ceph tell osd.0 injectargs -- '--osd_debug_op_order --osd_failsafe_full_ratio .98' >& $TMPFILE || return 1 check_response "osd_debug_op_order = 'true' osd_failsafe_full_ratio = '0.98'" + ceph tell osd.0 injectargs -- '--osd_failsafe_full_ratio' >& $TMPFILE || return 1 + check_response "Option --osd_failsafe_full_ratio requires an argument" } function test_mon_injectargs_SI() diff --git a/src/common/ceph_argparse.cc b/src/common/ceph_argparse.cc index eff6120df20..791ece79320 100644 --- a/src/common/ceph_argparse.cc +++ b/src/common/ceph_argparse.cc @@ -297,8 +297,9 @@ bool ceph_argparse_binary_flag(std::vector<const char*> &args, return r; } -static bool va_ceph_argparse_witharg(std::vector<const char*> &args, - std::vector<const char*>::iterator &i, std::string *ret, va_list ap) +static int va_ceph_argparse_witharg(std::vector<const char*> &args, + std::vector<const char*>::iterator &i, std::string *ret, + std::ostream &oss, va_list ap) { const char *first = *i; char tmp[strlen(first)+1]; @@ -309,7 +310,7 @@ static bool va_ceph_argparse_witharg(std::vector<const char*> &args, while (1) { const char *a = va_arg(ap, char*); if (a == NULL) - return false; + return 0; int strlen_a = strlen(a); char a2[strlen_a+1]; dashes_to_underscores(a, a2); @@ -317,18 +318,19 @@ static bool va_ceph_argparse_witharg(std::vector<const char*> &args, if (first[strlen_a] == '=') { *ret = first + strlen_a + 1; i = args.erase(i); - return true; + return 1; } else if (first[strlen_a] == '\0') { // find second part (or not) if (i+1 == args.end()) { - cerr << "Option " << *i << " requires an argument." << std::endl; - _exit(1); + oss << "Option " << *i << " requires an argument."; + i = args.erase(i); + return -EINVAL; } i = args.erase(i); *ret = *i; i = args.erase(i); - return true; + return 1; } } } @@ -339,21 +341,23 @@ bool ceph_argparse_witharg(std::vector<const char*> &args, std::vector<const char*>::iterator &i, T *ret, std::ostream &oss, ...) { - bool r; + int r; va_list ap; std::string str; va_start(ap, oss); - r = va_ceph_argparse_witharg(args, i, &str, ap); + r = va_ceph_argparse_witharg(args, i, &str, oss, ap); va_end(ap); - if (!r) { + if (r == 0) { return false; } - std::string err; - T myret = strict_str_convert(str.c_str(), &err); - *ret = myret; - if (!err.empty()) { - oss << err; + if (r == 1) { + std::string err; + T myret = strict_str_convert(str.c_str(), &err); + *ret = myret; + if (!err.empty()) { + oss << err; + } } return true; } @@ -371,14 +375,28 @@ template bool ceph_argparse_witharg<float>(std::vector<const char*> &args, std::ostream &oss, ...); bool ceph_argparse_witharg(std::vector<const char*> &args, + std::vector<const char*>::iterator &i, std::string *ret, + std::ostream &oss, ...) +{ + int r; + va_list ap; + va_start(ap, oss); + r = va_ceph_argparse_witharg(args, i, ret, oss, ap); + va_end(ap); + return r != 0; +} + +bool ceph_argparse_witharg(std::vector<const char*> &args, std::vector<const char*>::iterator &i, std::string *ret, ...) { - bool r; + int r; va_list ap; va_start(ap, ret); - r = va_ceph_argparse_witharg(args, i, ret, ap); + r = va_ceph_argparse_witharg(args, i, ret, cerr, ap); va_end(ap); - return r; + if (r < 0) + _exit(1); + return r != 0; } CephInitParameters ceph_argparse_early_args diff --git a/src/common/ceph_argparse.h b/src/common/ceph_argparse.h index e5845fb32d3..6ad0234df02 100644 --- a/src/common/ceph_argparse.h +++ b/src/common/ceph_argparse.h @@ -56,6 +56,9 @@ bool ceph_argparse_double_dash(std::vector<const char*> &args, bool ceph_argparse_flag(std::vector<const char*> &args, std::vector<const char*>::iterator &i, ...); bool ceph_argparse_witharg(std::vector<const char*> &args, + std::vector<const char*>::iterator &i, std::string *ret, + std::ostream &oss, ...); +bool ceph_argparse_witharg(std::vector<const char*> &args, std::vector<const char*>::iterator &i, std::string *ret, ...); template<class T> bool ceph_argparse_witharg(std::vector<const char*> &args, diff --git a/src/common/config.cc b/src/common/config.cc index 1efc1555608..41bb6a85f8c 100644 --- a/src/common/config.cc +++ b/src/common/config.cc @@ -486,6 +486,7 @@ int md_config_t::parse_option(std::vector<const char*>& args, } for (o = 0; o < NUM_CONFIG_OPTIONS; ++o) { + ostringstream err; const config_option *opt = config_optionsp + o; std::string as_option("--"); as_option += opt->name; @@ -509,8 +510,13 @@ int md_config_t::parse_option(std::vector<const char*>& args, } } } - else if (ceph_argparse_witharg(args, i, &val, + else if (ceph_argparse_witharg(args, i, &val, err, as_option.c_str(), (char*)NULL)) { + if (!err.str().empty()) { + *oss << err.str(); + ret = -EINVAL; + break; + } if (oss && ( ((opt->type == OPT_STR) || (opt->type == OPT_ADDR) || (opt->type == OPT_UUID)) && diff --git a/src/test/ceph_argparse.cc b/src/test/ceph_argparse.cc index 49bb962a887..f48f387f9ff 100644 --- a/src/test/ceph_argparse.cc +++ b/src/test/ceph_argparse.cc @@ -74,7 +74,10 @@ TEST(CephArgParse, SimpleArgParse) { found_foo = false; found_bar = ""; + bool baz_found = false; + std::string found_baz = ""; VectorContainer foo(FOO); + ostringstream err; for (std::vector<const char*>::iterator i = foo.arr.begin(); i != foo.arr.end(); ) { @@ -83,11 +86,17 @@ TEST(CephArgParse, SimpleArgParse) { } else if (ceph_argparse_witharg(foo.arr, i, &found_bar, "--bar", (char*)NULL)) { } + else if (ceph_argparse_witharg(foo.arr, i, &found_baz, err, "--baz", (char*)NULL)) { + ASSERT_NE(string(""), err.str()); + baz_found = true; + } else ++i; } ASSERT_EQ(found_foo, true); ASSERT_EQ(found_bar, ""); + ASSERT_EQ(baz_found, true); + ASSERT_EQ(found_baz, ""); found_foo = false; found_bar = ""; |