]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemd-hwdb update: Return non-zero exit code on error when --strict is used 8520/head
authorNicolas Boichat <drinkcat@google.com>
Tue, 27 Mar 2018 03:24:01 +0000 (11:24 +0800)
committerNicolas Boichat <drinkcat@chromium.org>
Mon, 23 Apr 2018 00:07:27 +0000 (08:07 +0800)
 - Add a new flag --strict to tell systemd-hwdb to return a
   non-zero code on error.
 - Make systemd-hwdb update return an error when any parsing
   error occurs (only if strict flag is set).

man/systemd-hwdb.xml
src/hwdb/hwdb.c

index 2b58388cffca44ccf1735713239cd47cfd7b5841..cd1df4a76eb7a1741d5c1a949167cb2a034721eb 100644 (file)
           <para>Alternate root path in the filesystem.</para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term><option>-s</option></term>
+        <term><option>--strict</option></term>
+        <listitem>
+          <para>When updating, return non-zero exit value on any parsing error.</para>
+        </listitem>
+      </varlistentry>
 
       <xi:include href="standard-options.xml" xpointer="help" />
     </variablelist>
index 67f693aae968f2887e45a0c9f0e736e74bb40048..99fcd1069a67b276f148717da4b299cf82b7b1f8 100644 (file)
@@ -34,6 +34,7 @@
 
 static const char *arg_hwdb_bin_dir = "/etc/udev";
 static const char *arg_root = "";
+static bool arg_strict;
 
 static const char * const conf_file_dirs[] = {
         "/etc/udev/hwdb.d",
@@ -489,7 +490,7 @@ static int import_file(struct trie *trie, const char *filename, uint16_t file_pr
         _cleanup_strv_free_ char **match_list = NULL;
         uint32_t line_number = 0;
         char *match = NULL;
-        int r;
+        int r = 0, err;
 
         f = fopen(filename, "re");
         if (!f)
@@ -524,6 +525,7 @@ static int import_file(struct trie *trie, const char *filename, uint16_t file_pr
                         if (line[0] == ' ') {
                                 log_syntax(NULL, LOG_WARNING, filename, line_number, EINVAL,
                                            "Match expected but got indented property \"%s\", ignoring line", line);
+                                r = -EINVAL;
                                 break;
                         }
 
@@ -534,9 +536,9 @@ static int import_file(struct trie *trie, const char *filename, uint16_t file_pr
                         if (!match)
                                 return -ENOMEM;
 
-                        r = strv_consume(&match_list, match);
-                        if (r < 0)
-                                return r;
+                        err = strv_consume(&match_list, match);
+                        if (err < 0)
+                                return err;
 
                         break;
 
@@ -544,7 +546,7 @@ static int import_file(struct trie *trie, const char *filename, uint16_t file_pr
                         if (len == 0) {
                                 log_syntax(NULL, LOG_WARNING, filename, line_number, EINVAL,
                                            "Property expected, ignoring record with no properties");
-
+                                r = -EINVAL;
                                 state = HW_NONE;
                                 strv_clear(match_list);
                                 break;
@@ -556,16 +558,18 @@ static int import_file(struct trie *trie, const char *filename, uint16_t file_pr
                                 if (!match)
                                         return -ENOMEM;
 
-                                r = strv_consume(&match_list, match);
-                                if (r < 0)
-                                        return r;
+                                err = strv_consume(&match_list, match);
+                                if (err < 0)
+                                        return err;
 
                                 break;
                         }
 
                         /* first data */
                         state = HW_DATA;
-                        insert_data(trie, match_list, line, filename, file_priority, line_number);
+                        err = insert_data(trie, match_list, line, filename, file_priority, line_number);
+                        if (err < 0)
+                                r = err;
                         break;
 
                 case HW_DATA:
@@ -579,12 +583,15 @@ static int import_file(struct trie *trie, const char *filename, uint16_t file_pr
                         if (line[0] != ' ') {
                                 log_syntax(NULL, LOG_WARNING, filename, line_number, EINVAL,
                                            "Property or empty line expected, got \"%s\", ignoring record", line);
+                                r = -EINVAL;
                                 state = HW_NONE;
                                 strv_clear(match_list);
                                 break;
                         }
 
-                        insert_data(trie, match_list, line, filename, file_priority, line_number);
+                        err = insert_data(trie, match_list, line, filename, file_priority, line_number);
+                        if (err < 0)
+                                r = err;
                         break;
                 };
         }
@@ -593,7 +600,7 @@ static int import_file(struct trie *trie, const char *filename, uint16_t file_pr
                 log_syntax(NULL, LOG_WARNING, filename, line_number, EINVAL,
                            "Property expected, ignoring record with no properties");
 
-        return 0;
+        return r;
 }
 
 static int hwdb_query(int argc, char *argv[], void *userdata) {
@@ -623,7 +630,7 @@ static int hwdb_update(int argc, char *argv[], void *userdata) {
         _cleanup_strv_free_ char **files = NULL;
         char **f;
         uint16_t file_priority = 1;
-        int r;
+        int r = 0, err;
 
         trie = new0(struct trie, 1);
         if (!trie)
@@ -641,13 +648,15 @@ static int hwdb_update(int argc, char *argv[], void *userdata) {
 
         trie->nodes_count++;
 
-        r = conf_files_list_strv(&files, ".hwdb", arg_root, 0, conf_file_dirs);
-        if (r < 0)
-                return log_error_errno(r, "Failed to enumerate hwdb files: %m");
+        err = conf_files_list_strv(&files, ".hwdb", arg_root, 0, conf_file_dirs);
+        if (err < 0)
+                return log_error_errno(err, "Failed to enumerate hwdb files: %m");
 
         STRV_FOREACH(f, files) {
                 log_debug("Reading file \"%s\"", *f);
-                import_file(trie, *f, file_priority++);
+                err = import_file(trie, *f, file_priority++);
+                if (err < 0 && arg_strict)
+                        r = err;
         }
 
         strbuf_complete(trie->strings);
@@ -671,11 +680,15 @@ static int hwdb_update(int argc, char *argv[], void *userdata) {
                 return -ENOMEM;
 
         mkdir_parents_label(hwdb_bin, 0755);
-        r = trie_store(trie, hwdb_bin);
-        if (r < 0)
-                return log_error_errno(r, "Failure writing database %s: %m", hwdb_bin);
+        err = trie_store(trie, hwdb_bin);
+        if (err < 0)
+                return log_error_errno(err, "Failure writing database %s: %m", hwdb_bin);
+
+        err = label_fix(hwdb_bin, 0);
+        if (err < 0)
+                return err;
 
-        return label_fix(hwdb_bin, 0);
+        return r;
 }
 
 static void help(void) {
@@ -683,6 +696,8 @@ static void help(void) {
                "Update or query the hardware database.\n\n"
                "  -h --help            Show this help\n"
                "     --version         Show package version\n"
+               "  -s --strict          When updating, return non-zero exit value on any parsing\n"
+               "                       error\n"
                "     --usr             Generate in " UDEVLIBEXECDIR " instead of /etc/udev\n"
                "  -r --root=PATH       Alternative root path in the filesystem\n\n"
                "Commands:\n"
@@ -701,6 +716,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "help",     no_argument,       NULL, 'h'         },
                 { "version",  no_argument,       NULL, ARG_VERSION },
                 { "usr",      no_argument,       NULL, ARG_USR     },
+                { "strict",   no_argument,       NULL, 's'         },
                 { "root",     required_argument, NULL, 'r'         },
                 {}
         };
@@ -710,7 +726,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "ut:r:h", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "ust:r:h", options, NULL)) >= 0) {
                 switch(c) {
 
                 case 'h':
@@ -724,6 +740,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_hwdb_bin_dir = UDEVLIBEXECDIR;
                         break;
 
+                case 's':
+                        arg_strict = true;
+                        break;
+
                 case 'r':
                         arg_root = optarg;
                         break;