[Bug 159861] New: d_type optimisation is broken for symlinks

Adam Sampson ats-kdebugs at offog.org
Tue Mar 25 23:30:44 CET 2008


------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
         
http://bugs.kde.org/show_bug.cgi?id=159861         
           Summary: d_type optimisation is broken for symlinks
           Product: kdelibs
           Version: unspecified
          Platform: Compiled Sources
        OS/Version: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: NOR
         Component: general
        AssignedTo: kdelibs-bugs kde org
        ReportedBy: ats-kdebugs offog org


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.


More information about the Kdelibs-bugs mailing list