[libvirt] [PATCH 10/10] Replace sscanf in PCI device address parsing

Matthias Bolte matthias.bolte at googlemail.com
Tue Mar 30 16:20:34 UTC 2010


This also fixes a problem with MinGW's GCC on Windows.
GCC complained bout the L modifier being unknown.
---
 src/util/pci.c |   59 +++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/src/util/pci.c b/src/util/pci.c
index 99ec22a..6aa2fe0 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -282,15 +282,26 @@ pciIterDevices(pciIterPredicate predicate,
     }
 
     while ((entry = readdir(dir))) {
-        unsigned domain, bus, slot, function;
+        unsigned int domain, bus, slot, function;
         pciDevice *check;
+        char *tmp;
 
         /* Ignore '.' and '..' */
         if (entry->d_name[0] == '.')
             continue;
 
-        if (sscanf(entry->d_name, "%x:%x:%x.%x",
-                   &domain, &bus, &slot, &function) < 4) {
+        /* expected format: <domain>:<bus>:<slot>.<function> */
+        if (/* domain */
+            virStrToLong_ui(entry->d_name, &tmp, 16, &domain) < 0 ||
+            tmp == NULL || *tmp != ':' ||
+            /* bus */
+            virStrToLong_ui(tmp + 1, &tmp, 16, &bus) < 0 ||
+            tmp == NULL || *tmp != ':' ||
+            /* slot */
+            virStrToLong_ui(tmp + 1, &tmp, 16, &slot) < 0 ||
+            tmp == NULL || *tmp != '.' ||
+            /* function */
+            virStrToLong_ui(tmp + 1, NULL, 16, &function) < 0) {
             VIR_WARN("Unusual entry in " PCI_SYSFS "devices: %s", entry->d_name);
             continue;
         }
@@ -914,10 +925,9 @@ pciWaitForDeviceCleanup(pciDevice *dev, const char *matcher)
     FILE *fp;
     char line[160];
     unsigned long long start, end;
-    int consumed;
     char *rest;
-    unsigned long long domain;
-    int bus, slot, function;
+    char *tmp;
+    unsigned int domain, bus, slot, function;
     int in_matching_device;
     int ret;
     size_t match_depth;
@@ -945,10 +955,18 @@ pciWaitForDeviceCleanup(pciDevice *dev, const char *matcher)
          * of these situations
          */
         if (in_matching_device && (strspn(line, " ") == (match_depth + 2))) {
-            if (sscanf(line, "%Lx-%Lx : %n", &start, &end, &consumed) != 2)
+            tmp = line + strspn(line, " ");
+
+            /* expected format: <start>-<end> : <suffix> */
+            if (/* start */
+                virStrToLong_ull(tmp, &tmp, 16, &start) < 0 ||
+                tmp == NULL || *tmp != '-' ||
+                /* end */
+                virStrToLong_ull(tmp + 1, &tmp, 16, &end) < 0 ||
+                tmp == NULL || ! STRPREFIX(tmp, " : "))
                 continue;
 
-            rest = line + consumed;
+            rest = tmp + 3; /* = strlen(" : ") */
             if (STRPREFIX(rest, matcher)) {
                 ret = 1;
                 break;
@@ -956,11 +974,26 @@ pciWaitForDeviceCleanup(pciDevice *dev, const char *matcher)
         }
         else {
             in_matching_device = 0;
-            if (sscanf(line, "%Lx-%Lx : %n", &start, &end, &consumed) != 2)
-                continue;
-
-            rest = line + consumed;
-            if (sscanf(rest, "%Lx:%x:%x.%x", &domain, &bus, &slot, &function) != 4)
+            tmp = line + strspn(line, " ");
+
+            /* expected format: <start>-<end> : <domain>:<bus>:<slot>.<function> */
+            if (/* start */
+                virStrToLong_ull(tmp, &tmp, 16, &start) < 0 ||
+                tmp == NULL || *tmp != '-' ||
+                /* end */
+                virStrToLong_ull(tmp + 1, &tmp, 16, &end) < 0 ||
+                tmp == NULL || ! STRPREFIX(tmp, " : ") ||
+                /* domain */
+                virStrToLong_ui(tmp + 3, &tmp, 16, &domain) < 0 ||
+                tmp == NULL || *tmp != ':' ||
+                /* bus */
+                virStrToLong_ui(tmp + 1, &tmp, 16, &bus) < 0 ||
+                tmp == NULL || *tmp != ':' ||
+                /* slot */
+                virStrToLong_ui(tmp + 1, &tmp, 16, &slot) < 0 ||
+                tmp == NULL || *tmp != '.' ||
+                /* function */
+                virStrToLong_ui(tmp + 1, &tmp, 16, &function) < 0)
                 continue;
 
             if (domain != dev->domain || bus != dev->bus || slot != dev->slot ||
-- 
1.6.3.3




More information about the libvir-list mailing list