Bug 159861 - d_type optimisation is broken for symlinks
Summary: d_type optimisation is broken for symlinks
Status: RESOLVED DUPLICATE of bug 150307
Alias: None
Product: kdelibs
Classification: Frameworks and Libraries
Component: general (show other bugs)
Version: unspecified
Platform: Compiled Sources Linux
: NOR normal
Target Milestone: ---
Assignee: kdelibs bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-03-25 23:30 UTC by Adam Sampson
Modified: 2008-03-26 12:19 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments
Fix for this problem in kdelibs (but please check elsewhere too!) (1.59 KB, patch)
2008-03-25 23:31 UTC, Adam Sampson
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Adam Sampson 2008-03-25 23:30:43 UTC
Version:            (using KDE 4.0.2)
Installed from:    Compiled From Sources
Compiler:          GCC 4.2.3 
OS:                Linux

A couple of libraries in kdelibs make use of the d_type field in struct dirent on systems such as Linux; this avoids the significant overhead of a stat call for each directory entry. For examples, see kdecore/kernel/kstandarddirs.cpp or kded/vfolder_menu.cpp, each of which has two instances of code like the following:

#ifdef HAVE_DIRENT_D_TYPE
            isDir = ep->d_type == DT_DIR;
            isReg = ep->d_type == DT_REG;

            if (ep->d_type == DT_UNKNOWN)
#endif
            {
                KDE_struct_stat buff;
                if ( KDE_stat( QFile::encodeName(pathfn), &buff ) != 0 ) {
                    ...
                }
                isReg = S_ISREG (buff.st_mode);
                isDir = S_ISDIR (buff.st_mode);
            }

However, this code behaves incorrectly when the directory entry is a symlink -- in which case readdir returns ep->d_type == DT_LNK, but stat will reference the symlink and S_ISREG will return true.

The result of this is that kbuildsyscoca (and anything else using this code) will silently ignore files and directories that are symlinks if kdelibs was built with HAVE_DIRENT_D_TYPE. This makes KDE4 not work at all if it's installed using a symlink-based packaging system such as stow, since (for example) it won't be able to resolve any MIME types.

The fix I've applied is to change the if test to:

            if (ep->d_type == DT_UNKNOWN || ep->d_type == DT_LNK)

... so that when it finds a symlink, it'll fall back to using stat to dereference it. This makes kbuildsycoca work properly again for me.

Since I found the same code in four places in kdelibs, it doesn't seem entirely unreasonable that it might have been copied elsewhere too; it would probably be worth scanning the entire repository for "->d_type" and checking the same bug doesn't exist elsewhere.
Comment 1 Adam Sampson 2008-03-25 23:31:29 UTC
Created attachment 24052 [details]
Fix for this problem in kdelibs (but please check elsewhere too!)
Comment 2 David Faure 2008-03-26 12:19:54 UTC
Checked elsewhere: no other use of d_type: http://lxr.kde.org/ident?i=d_type

Will apply.

*** This bug has been marked as a duplicate of 150307 ***