[libvirt] [PATCH] util: Implement and use virFileIsRegular() rather than d_type

Stefan Berger stefanb at linux.vnet.ibm.com
Thu Jun 7 12:31:42 UTC 2018


On 06/06/2018 12:57 PM, Eric Blake wrote:
> On 06/06/2018 11:37 AM, Stefan Berger wrote:
>> The dirent's d_type field is not portable to all platforms. So we have
>> to use stat() to determine the type of file for the functions that need
>> to be cross-platform. Fix virFileChownFiles() by calling the new
>> virFileIsRegular() function.
>>
>> Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
>> ---
>>   src/libvirt_private.syms |  1 +
>>   src/util/virfile.c       | 17 +++++++++++++----
>>   src/util/virfile.h       |  1 +
>>   3 files changed, 15 insertions(+), 4 deletions(-)
>
>> +
>> +bool
>> +virFileIsRegular(const char *path)
>> +{
>> +    struct stat s;
>> +    return (stat(path, &s) == 0) && S_ISREG(s.st_mode);
>
> This always does a stat.
>
>> +}
>> +
>> +
>>   /**
>>    * virFileExists: Check for presence of file
>>    * @path: Path of file to check
>> @@ -3005,12 +3014,13 @@ int virFileChownFiles(const char *name,
>>           return -1;
>>         while ((direrr = virDirRead(dir, &ent, name)) > 0) {
>> -        if (ent->d_type != DT_REG)
>> -            continue;
>
> And this was the non-portable code you're getting rid of, which was 
> already buggy - even on systems with d_type, a return of DT_UNKNOWN 
> requires a stat() rather than a blind continue. However, your 
> replacement is pessimizing platforms where d_type is reliable, by 
> making us do a stat() where we previously did not need to.
>
> Better would be using macros that use d_type where possible, and fall 
> back to stat() only when d_type does not exist or is DT_UNKNOWN; for 
> example, here's how gnulib does it:
>
> #if HAVE_STRUCT_DIRENT_D_TYPE
> /* True if the type of the directory entry D is known.  */
> # define DT_IS_KNOWN(d) ((d)->d_type != DT_UNKNOWN)
> /* True if the type of the directory entry D must be T.  */
> # define DT_MUST_BE(d, t) ((d)->d_type == (t))
> # define D_TYPE(d) ((d)->d_type)
> #else
> # define DT_IS_KNOWN(d) false
> # define DT_MUST_BE(d, t) false
> # define D_TYPE(d) DT_UNKNOWN
>
> # undef DT_UNKNOWN
> # define DT_UNKNOWN 0
>
> (although we have to be careful with licensing, because that is from 
> lib/fts.c which is marked GPLv3+).
>
gnulib seems to implement readdir() but they also set d_type there and 
what you are showing above is unfortunately not in a header file but in 
fts.c :-(

I guess for our purposes it would be good enough to have an equivalent 
of HAVE_STRUCT_DIRENT_D_TYPE set by test-compiling in configure?





More information about the libvir-list mailing list