Browse Source

[2559] Merge branch 'master' into trac2559

Stephen Morris 12 years ago
parent
commit
5237d9415f

+ 16 - 1
ChangeLog

@@ -1,4 +1,19 @@
-5XX.	[func]		tomek
+552.    [bug]       shane
+    Build on Raspberry PI.
+	The main issue was use of char for reading from input streams,
+	which is incorrect, as EOF is returned as an int -1, which would
+	then get cast into a char -1.
+	A number of other minor issues were also fixed.
+	(Trac #2571, git 525333e187cc4bbbbde288105c9582c1024caa4a)
+
+551.    [bug]       shane
+	Kill msgq if we cannot connect to it on startup.
+	When the boss process was unable to connect to the msgq, it would
+	exit. However, it would leave the msgq process running. This has
+	been fixed, and the msgq is now stopped in this case.
+	(Trac #2608, git 016925ef2437e0396127e135c937d3a55539d224)
+
+550.	[func]		tomek
 	b10-dhcp4: The DHCPv4 server now generates a server identifier
 	the first time it is run. The identifier is preserved in a file
 	across server restarts.

+ 2 - 0
src/bin/bind10/bind10_src.py.in

@@ -491,6 +491,8 @@ class BoB:
 
             # if we have been trying for "a while" give up
             if (time.time() - cc_connect_start) > self.msgq_timeout:
+                if msgq_proc.process:
+                    msgq_proc.process.kill()
                 logger.error(BIND10_CONNECTING_TO_CC_FAIL)
                 raise CChannelConnectError("Unable to connect to c-channel after 5 seconds")
 

+ 60 - 59
src/lib/cc/data.cc

@@ -16,6 +16,7 @@
 
 #include <cc/data.h>
 
+#include <cstring>
 #include <cassert>
 #include <climits>
 #include <map>
@@ -31,7 +32,7 @@
 using namespace std;
 
 namespace {
-const char* WHITESPACE = " \b\f\n\r\t";
+const char* const WHITESPACE = " \b\f\n\r\t";
 } // end anonymous namespace
 
 namespace isc {
@@ -183,7 +184,7 @@ throwJSONError(const std::string& error, const std::string& file, int line,
 }
 
 std::ostream&
-operator<<(std::ostream &out, const Element& e) {
+operator<<(std::ostream& out, const Element& e) {
     return (out << e.str());
 }
 
@@ -240,8 +241,9 @@ Element::createMap() {
 //
 namespace {
 bool
-char_in(const char c, const char *chars) {
-    for (size_t i = 0; i < strlen(chars); ++i) {
+charIn(const int c, const char* chars) {
+    const size_t chars_len = std::strlen(chars);
+    for (size_t i = 0; i < chars_len; ++i) {
         if (chars[i] == c) {
             return (true);
         }
@@ -250,9 +252,9 @@ char_in(const char c, const char *chars) {
 }
 
 void
-skip_chars(std::istream &in, const char *chars, int& line, int& pos) {
-    char c = in.peek();
-    while (char_in(c, chars) && c != EOF) {
+skipChars(std::istream& in, const char* chars, int& line, int& pos) {
+    int c = in.peek();
+    while (charIn(c, chars) && c != EOF) {
         if (c == '\n') {
             ++line;
             pos = 1;
@@ -270,21 +272,21 @@ skip_chars(std::istream &in, const char *chars, int& line, int& pos) {
 //
 // the character found is left on the stream
 void
-skip_to(std::istream &in, const std::string& file, int& line,
-        int& pos, const char* chars, const char* may_skip="")
+skipTo(std::istream& in, const std::string& file, int& line,
+       int& pos, const char* chars, const char* may_skip="")
 {
-    char c = in.get();
+    int c = in.get();
     ++pos;
     while (c != EOF) {
         if (c == '\n') {
             pos = 1;
             ++line;
         }
-        if (char_in(c, may_skip)) {
+        if (charIn(c, may_skip)) {
             c = in.get();
             ++pos;
-        } else if (char_in(c, chars)) {
-            while(char_in(in.peek(), may_skip)) {
+        } else if (charIn(c, chars)) {
+            while (charIn(in.peek(), may_skip)) {
                 if (in.peek() == '\n') {
                     pos = 1;
                     ++line;
@@ -296,7 +298,7 @@ skip_to(std::istream &in, const std::string& file, int& line,
             --pos;
             return;
         } else {
-            throwJSONError(std::string("'") + c + "' read, one of \"" + chars + "\" expected", file, line, pos);
+            throwJSONError(std::string("'") + std::string(1, c) + "' read, one of \"" + chars + "\" expected", file, line, pos);
         }
     }
     throwJSONError(std::string("EOF read, one of \"") + chars + "\" expected", file, line, pos);
@@ -305,12 +307,11 @@ skip_to(std::istream &in, const std::string& file, int& line,
 // TODO: Should we check for all other official escapes here (and
 // error on the rest)?
 std::string
-str_from_stringstream(std::istream &in, const std::string& file, const int line,
-                      int& pos) throw (JSONError)
+strFromStringstream(std::istream& in, const std::string& file,
+                    const int line, int& pos) throw (JSONError)
 {
-    char c;
     std::stringstream ss;
-    c = in.get();
+    int c = in.get();
     ++pos;
     if (c == '"') {
         c = in.get();
@@ -354,7 +355,7 @@ str_from_stringstream(std::istream &in, const std::string& file, const int line,
             in.get();
             ++pos;
         }
-        ss << c;
+        ss.put(c);
         c = in.get();
         ++pos;
     }
@@ -365,7 +366,7 @@ str_from_stringstream(std::istream &in, const std::string& file, const int line,
 }
 
 std::string
-word_from_stringstream(std::istream &in, int& pos) {
+wordFromStringstream(std::istream& in, int& pos) {
     std::stringstream ss;
     while (isalpha(in.peek())) {
         ss << (char) in.get();
@@ -374,8 +375,8 @@ word_from_stringstream(std::istream &in, int& pos) {
     return (ss.str());
 }
 
-static std::string
-number_from_stringstream(std::istream &in, int& pos) {
+std::string
+numberFromStringstream(std::istream& in, int& pos) {
     std::stringstream ss;
     while (isdigit(in.peek()) || in.peek() == '+' || in.peek() == '-' ||
            in.peek() == '.' || in.peek() == 'e' || in.peek() == 'E') {
@@ -389,13 +390,13 @@ number_from_stringstream(std::istream &in, int& pos) {
 // that can also hold an e value? (and have specific getters if the
 // value is larger than an int can handle)
 ElementPtr
-from_stringstream_number(std::istream &in, int &pos) {
+fromStringstreamNumber(std::istream& in, int& pos) {
     long int i;
     double d = 0.0;
     bool is_double = false;
-    char *endptr;
+    char* endptr;
 
-    std::string number = number_from_stringstream(in, pos);
+    std::string number = numberFromStringstream(in, pos);
 
     i = strtol(number.c_str(), &endptr, 10);
     if (*endptr != '\0') {
@@ -422,10 +423,10 @@ from_stringstream_number(std::istream &in, int &pos) {
 }
 
 ElementPtr
-from_stringstream_bool(std::istream &in, const std::string& file,
-                       const int line, int& pos)
+fromStringstreamBool(std::istream& in, const std::string& file,
+                     const int line, int& pos)
 {
-    const std::string word = word_from_stringstream(in, pos);
+    const std::string word = wordFromStringstream(in, pos);
     if (boost::iequals(word, "True")) {
         return (Element::create(true));
     } else if (boost::iequals(word, "False")) {
@@ -438,10 +439,10 @@ from_stringstream_bool(std::istream &in, const std::string& file,
 }
 
 ElementPtr
-from_stringstream_null(std::istream &in, const std::string& file,
-                       const int line, int& pos)
+fromStringstreamNull(std::istream& in, const std::string& file,
+                     const int line, int& pos)
 {
-    const std::string word = word_from_stringstream(in, pos);
+    const std::string word = wordFromStringstream(in, pos);
     if (boost::iequals(word, "null")) {
         return (Element::create());
     } else {
@@ -451,26 +452,26 @@ from_stringstream_null(std::istream &in, const std::string& file,
 }
 
 ElementPtr
-from_stringstream_string(std::istream& in, const std::string& file, int& line,
-                         int& pos)
+fromStringstreamString(std::istream& in, const std::string& file, int& line,
+                       int& pos)
 {
-    return (Element::create(str_from_stringstream(in, file, line, pos)));
+    return (Element::create(strFromStringstream(in, file, line, pos)));
 }
 
 ElementPtr
-from_stringstream_list(std::istream &in, const std::string& file, int& line,
-                       int& pos)
+fromStringstreamList(std::istream& in, const std::string& file, int& line,
+                     int& pos)
 {
-    char c = 0;
+    int c = 0;
     ElementPtr list = Element::createList();
     ConstElementPtr cur_list_element;
 
-    skip_chars(in, WHITESPACE, line, pos);
+    skipChars(in, WHITESPACE, line, pos);
     while (c != EOF && c != ']') {
         if (in.peek() != ']') {
             cur_list_element = Element::fromJSON(in, file, line, pos);
             list->add(cur_list_element);
-            skip_to(in, file, line, pos, ",]", WHITESPACE);
+            skipTo(in, file, line, pos, ",]", WHITESPACE);
         }
         c = in.get();
         pos++;
@@ -479,12 +480,12 @@ from_stringstream_list(std::istream &in, const std::string& file, int& line,
 }
 
 ElementPtr
-from_stringstream_map(std::istream &in, const std::string& file, int& line,
-                      int& pos)
+fromStringstreamMap(std::istream& in, const std::string& file, int& line,
+                    int& pos)
 {
     ElementPtr map = Element::createMap();
-    skip_chars(in, WHITESPACE, line, pos);
-    char c = in.peek();
+    skipChars(in, WHITESPACE, line, pos);
+    int c = in.peek();
     if (c == EOF) {
         throwJSONError(std::string("Unterminated map, <string> or } expected"), file, line, pos);
     } else if (c == '}') {
@@ -492,9 +493,9 @@ from_stringstream_map(std::istream &in, const std::string& file, int& line,
         c = in.get();
     } else {
         while (c != EOF && c != '}') {
-            std::string key = str_from_stringstream(in, file, line, pos);
+            std::string key = strFromStringstream(in, file, line, pos);
 
-            skip_to(in, file, line, pos, ":", WHITESPACE);
+            skipTo(in, file, line, pos, ":", WHITESPACE);
             // skip the :
             in.get();
             pos++;
@@ -502,14 +503,14 @@ from_stringstream_map(std::istream &in, const std::string& file, int& line,
             ConstElementPtr value = Element::fromJSON(in, file, line, pos);
             map->set(key, value);
 
-            skip_to(in, file, line, pos, ",}", WHITESPACE);
+            skipTo(in, file, line, pos, ",}", WHITESPACE);
             c = in.get();
             pos++;
         }
     }
     return (map);
 }
-}
+} // unnamed namespace
 
 std::string
 Element::typeToName(Element::types type) {
@@ -575,13 +576,13 @@ Element::fromJSON(std::istream& in, const std::string& file_name)
 }
 
 ElementPtr
-Element::fromJSON(std::istream &in, const std::string& file, int& line,
+Element::fromJSON(std::istream& in, const std::string& file, int& line,
                   int& pos) throw(JSONError)
 {
-    char c = 0;
+    int c = 0;
     ElementPtr element;
     bool el_read = false;
-    skip_chars(in, WHITESPACE, line, pos);
+    skipChars(in, WHITESPACE, line, pos);
     while (c != EOF && !el_read) {
         c = in.get();
         pos++;
@@ -600,7 +601,7 @@ Element::fromJSON(std::istream &in, const std::string& file, int& line,
             case '+':
             case '.':
                 in.putback(c);
-                element = from_stringstream_number(in, pos);
+                element = fromStringstreamNumber(in, pos);
                 el_read = true;
                 break;
             case 't':
@@ -608,32 +609,32 @@ Element::fromJSON(std::istream &in, const std::string& file, int& line,
             case 'f':
             case 'F':
                 in.putback(c);
-                element = from_stringstream_bool(in, file, line, pos);
+                element = fromStringstreamBool(in, file, line, pos);
                 el_read = true;
                 break;
             case 'n':
             case 'N':
                 in.putback(c);
-                element = from_stringstream_null(in, file, line, pos);
+                element = fromStringstreamNull(in, file, line, pos);
                 el_read = true;
                 break;
             case '"':
                 in.putback('"');
-                element = from_stringstream_string(in, file, line, pos);
+                element = fromStringstreamString(in, file, line, pos);
                 el_read = true;
                 break;
             case '[':
-                element = from_stringstream_list(in, file, line, pos);
+                element = fromStringstreamList(in, file, line, pos);
                 el_read = true;
                 break;
             case '{':
-                element = from_stringstream_map(in, file, line, pos);
+                element = fromStringstreamMap(in, file, line, pos);
                 el_read = true;
                 break;
             case EOF:
                 break;
             default:
-                throwJSONError(std::string("error: unexpected character ") + c, file, line, pos);
+                throwJSONError(std::string("error: unexpected character ") + std::string(1, c), file, line, pos);
                 break;
         }
     }
@@ -645,12 +646,12 @@ Element::fromJSON(std::istream &in, const std::string& file, int& line,
 }
 
 ElementPtr
-Element::fromJSON(const std::string &in) {
+Element::fromJSON(const std::string& in) {
     std::stringstream ss;
     ss << in;
     int line = 1, pos = 1;
     ElementPtr result(fromJSON(ss, "<string>", line, pos));
-    skip_chars(ss, WHITESPACE, line, pos);
+    skipChars(ss, WHITESPACE, line, pos);
     // ss must now be at end
     if (ss.peek() != EOF) {
         throwJSONError("Extra data", "<string>", line, pos);

+ 4 - 0
src/lib/cc/tests/data_unittests.cc

@@ -91,6 +91,10 @@ TEST(Element, from_and_to_json) {
     sv.push_back("-1");
     sv.push_back("-1.234");
     sv.push_back("-123.456");
+    // We should confirm that our string handling is 8-bit clean.
+    // At one point we were using char-length data and comparing to EOF,
+    // which means that character '\xFF' would not parse properly.
+    sv.push_back("\"\xFF\"");
 
     BOOST_FOREACH(const std::string& s, sv) {
         // test << operator, which uses Element::str()

+ 1 - 1
tests/tools/perfdhcp/command_options.cc

@@ -134,7 +134,7 @@ CommandOptions::parse(int argc, char** const argv) {
 
 bool
 CommandOptions::initialize(int argc, char** argv) {
-    char opt = 0;               // Subsequent options returned by getopt()
+    int opt = 0;                // Subsequent options returned by getopt()
     std::string drop_arg;       // Value of -D<value>argument
     size_t percent_loc = 0;     // Location of % sign in -D<value>
     double drop_percent = 0;    // % value (1..100) in -D<value%>