[libvirt] [PATCH] nodeinfo: Make sure we always reset errno before calling readdir
Eric Blake
eblake at redhat.com
Thu Apr 10 15:22:42 UTC 2014
On 04/10/2014 08:38 AM, Natanael Copa wrote:
>>> - errno = 0;
>>> - while ((cpudirent = readdir(cpudir))) {
>>> + for (errno = 0; (cpudirent = readdir(cpudir)); errno = 0) {
>>> if (sscanf(cpudirent->d_name, "cpu%u", &cpu) != 1)
>>> continue;
>>
>> Good catch. However, the code is still buggy even after your fix. We
>> are missing:
>>
>> if (errno)
>> break;
>>
>> before attempting the sscanf.
>
> Why? if readdir fails it should return NULL and the for() loop
> condition should break the loop. If readdir does not return NULL it
> didn't fail and errno value is undefined.
Uggh, you're right. Yet another reason why I hate the readdir() interface.
>
> I suppose we could use helper function to make it more readable:
>
> static struct dirent *virReaddir(DIR *dirp)
> {
> errno = 0;
> return readdir(dirp);
> }
Or maybe:
int virReaddir(DIR *dirp, struct dirent **ent)
{
errno = 0;
*ent = readdir(dirp);
if (!*ent && errno) {
virReportSystemError(errno, _("unable to read directory"))
return -1;
}
return *ent ? 1 : 0;
}
and used as:
while ((ret = virReaddir(dirp, &entry)) > 0) {
process entry
}
if (ret < 0)
goto error;
> while ((cpudirent = virReaddir(cpudir))
>
>> Furthermore, sscanf() is undefined on
>> overflow; while the cpudir is unlikely to be giving us integers that
>> overflow, it would be nicer to not use sscanf in the first place. It's
>> more than just the improper use of readdir that needs fixing here.
>>
>> I'm debating whether to push this now and fix the rest as a followup, or
>> whether to do a v2 that fixes it all at once.
>
> I'd say fix the current bug first and do the clean up in separate commit.
Saving sscanf() abuse cleanup for a separate commit is just fine.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 604 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20140410/eb376cba/attachment-0001.sig>
More information about the libvir-list
mailing list