Replace sscanf in PCI device address parsing

This also fixes a problem with MinGW's GCC on Windows. GCC complains
about the L modifier being unknown.

Parsing in pciIterDevices is stricter now and doesn't accept trailing
characters after the actual <domain>:<bus>:<slot>.<function> sequence
anymore.

Parsing in pciWaitForDeviceCleanup is also stricter now and expects
the <start>-<end> : <domain>:<bus>:<slot>.<function> sequence to be
terminated by \n.

Change domain from unsigned long long to unsigned int in
pciWaitForDeviceCleanup, because everywhere else domain is handled as
unsigned int too.
This commit is contained in:
Matthias Bolte 2010-03-30 17:31:19 +02:00
parent 57dab74804
commit d13eb9fc95

View File

@ -282,15 +282,23 @@ pciIterDevices(pciIterPredicate predicate,
} }
while ((entry = readdir(dir))) { while ((entry = readdir(dir))) {
unsigned domain, bus, slot, function; unsigned int domain, bus, slot, function;
pciDevice *check; pciDevice *check;
char *tmp;
/* Ignore '.' and '..' */ /* Ignore '.' and '..' */
if (entry->d_name[0] == '.') if (entry->d_name[0] == '.')
continue; continue;
if (sscanf(entry->d_name, "%x:%x:%x.%x", /* expected format: <domain>:<bus>:<slot>.<function> */
&domain, &bus, &slot, &function) < 4) { if (/* domain */
virStrToLong_ui(entry->d_name, &tmp, 16, &domain) < 0 || *tmp != ':' ||
/* bus */
virStrToLong_ui(tmp + 1, &tmp, 16, &bus) < 0 || *tmp != ':' ||
/* slot */
virStrToLong_ui(tmp + 1, &tmp, 16, &slot) < 0 || *tmp != '.' ||
/* function */
virStrToLong_ui(tmp + 1, NULL, 16, &function) < 0) {
VIR_WARN("Unusual entry in " PCI_SYSFS "devices: %s", entry->d_name); VIR_WARN("Unusual entry in " PCI_SYSFS "devices: %s", entry->d_name);
continue; continue;
} }
@ -913,11 +921,9 @@ pciWaitForDeviceCleanup(pciDevice *dev, const char *matcher)
{ {
FILE *fp; FILE *fp;
char line[160]; char line[160];
char *tmp;
unsigned long long start, end; unsigned long long start, end;
int consumed; unsigned int domain, bus, slot, function;
char *rest;
unsigned long long domain;
int bus, slot, function;
int in_matching_device; int in_matching_device;
int ret; int ret;
size_t match_depth; size_t match_depth;
@ -945,22 +951,36 @@ pciWaitForDeviceCleanup(pciDevice *dev, const char *matcher)
* of these situations * of these situations
*/ */
if (in_matching_device && (strspn(line, " ") == (match_depth + 2))) { if (in_matching_device && (strspn(line, " ") == (match_depth + 2))) {
if (sscanf(line, "%Lx-%Lx : %n", &start, &end, &consumed) != 2) /* expected format: <start>-<end> : <suffix> */
if (/* start */
virStrToLong_ull(line, &tmp, 16, &start) < 0 || *tmp != '-' ||
/* end */
virStrToLong_ull(tmp + 1, &tmp, 16, &end) < 0 ||
(tmp = STRSKIP(tmp, " : ")) == NULL)
continue; continue;
rest = line + consumed; if (STRPREFIX(tmp, matcher)) {
if (STRPREFIX(rest, matcher)) {
ret = 1; ret = 1;
break; break;
} }
} }
else { else {
in_matching_device = 0; in_matching_device = 0;
if (sscanf(line, "%Lx-%Lx : %n", &start, &end, &consumed) != 2)
continue;
rest = line + consumed; /* expected format: <start>-<end> : <domain>:<bus>:<slot>.<function> */
if (sscanf(rest, "%Lx:%x:%x.%x", &domain, &bus, &slot, &function) != 4) if (/* start */
virStrToLong_ull(line, &tmp, 16, &start) < 0 || *tmp != '-' ||
/* end */
virStrToLong_ull(tmp + 1, &tmp, 16, &end) < 0 ||
(tmp = STRSKIP(tmp, " : ")) == NULL ||
/* domain */
virStrToLong_ui(tmp, &tmp, 16, &domain) < 0 || *tmp != ':' ||
/* bus */
virStrToLong_ui(tmp + 1, &tmp, 16, &bus) < 0 || *tmp != ':' ||
/* slot */
virStrToLong_ui(tmp + 1, &tmp, 16, &slot) < 0 || *tmp != '.' ||
/* function */
virStrToLong_ui(tmp + 1, &tmp, 16, &function) < 0 || *tmp != '\n')
continue; continue;
if (domain != dev->domain || bus != dev->bus || slot != dev->slot || if (domain != dev->domain || bus != dev->bus || slot != dev->slot ||