Changeset 1047 for trunk/src


Ignore:
Timestamp:
Sep 3, 2011, 8:07:07 PM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

OS/2: QDir: Filter out "." and ".." from root directories.

This is necessary to have consistent behavior since some IFS drivers
report them (HPFS, JFS) and some don't. We remove dots instead of
adding them because it is simpler and because this makes us compatible
with Windows where dots are always removed (per MSDN).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/corelib/io/qfsfileengine_iterator_os2.cpp

    r848 r1047  
    7171public:
    7272    inline QFSFileEngineIteratorPlatformSpecificData()
    73         : dir(0), dirEntry(0), done(false)
     73        : dir(0), dirEntry(0), root(false), seenDot(false), seenDotDot(false)
     74        , done(false)
    7475#if defined(_POSIX_THREAD_SAFE_FUNCTIONS)
    7576          , mt_file(0)
     
    7980    DIR *dir;
    8081    dirent *dirEntry;
    81     bool done;
     82    bool root : 1;
     83    bool seenDot : 1;
     84    bool seenDotDot : 1;
     85    bool done : 1;
    8286
    8387#if defined(_POSIX_THREAD_SAFE_FUNCTIONS)
     
    9397public:
    9498    inline QFSFileEngineIteratorPlatformSpecificData()
    95         : done(false), hdir(HDIR_CREATE)
     99        : root(false), seenDot(false), seenDotDot(false)
     100        , done(false), hdir(HDIR_CREATE)
    96101    {
    97102        memset(&findBuf, 0, sizeof(findBuf));
    98103    }
     104
     105    APIRET filterOutDots();
    99106
    100107    static QDateTime convertFileDateTime(FDATE fdate, FTIME ftime);
     
    102109    void resetFileInfo() { d_ptr->clear(); }
    103110
    104     bool done;
     111    bool root : 1;
     112    bool seenDot : 1;
     113    bool seenDotDot : 1;
     114    bool done : 1;
    105115    HDIR hdir;
    106116    FILEFINDBUF3L findBuf;
     
    120130#if defined(_POSIX_THREAD_SAFE_FUNCTIONS)
    121131    if (::readdir_r(platform->dir, platform->mt_file, &platform->dirEntry) != 0)
    122         platform->done = true;
     132        platform->dirEntry = 0;
     133    // filter out "." and ".." from root to have consistent behavior across
     134    // different IFSes (some report them, some don't).
     135    while (platform->root && platform->dirEntry &&
     136           ((!platform->seenDot &&
     137             (platform->seenDot = qstrcmp(platform->dirEntry->d_name, ".")) == 0) ||
     138            (!platform->seenDotDot &&
     139             (platform->seenDotDot = qstrcmp(platform->dirEntry->d_name, "..")) == 0)))
     140        if (::readdir_r(platform->dir, platform->mt_file, &platform->dirEntry) != 0)
     141            platform->dirEntry = 0;
    123142#else
    124143    // ### add local lock to prevent breaking reentrancy
    125144    platform->dirEntry = ::readdir(platform->dir);
     145    // filter out "." and ".." from root to have consistent behavior across
     146    // different IFSes (some report them, some don't).
     147    while (platform->root && platform->dirEntry &&
     148           ((!platform->seenDot &&
     149             (platform->seenDot = qstrcmp(platform->dirEntry->d_name, ".")) == 0) ||
     150            (!platform->seenDotDot &&
     151             (platform->seenDotDot = qstrcmp(platform->dirEntry->d_name, "..")) == 0)))
     152        platform->dirEntry = ::readdir(platform->dir);
    126153#endif // _POSIX_THREAD_SAFE_FUNCTIONS
    127154    if (!platform->dirEntry) {
     
    142169        return;
    143170    }
     171
     172    if (platform->root && platform->filterOutDots() != NO_ERROR)
     173        return;
    144174
    145175    // set QFileInfo from find buffer
     
    200230            path.append(QLatin1Char('/'));
    201231        APIRET arc = NO_ERROR;
    202         if (path.size() >= 2 && path.at(0).isLetter() && path.at(1) == QLatin1Char(':')) {
     232        if (path.length() >= 2 && path.at(0).isLetter() && path.at(1) == QLatin1Char(':')) {
     233            that->platform->root = path.length() == 3 && (path.at(2) == QLatin1Char('/'));
    203234            // check that the drive is ready before trying to open it which reduces
    204235            // delays and noise for drives with no media inserted
     
    219250                DosClose(hdrv);
    220251            }
     252        } else {
     253            that->platform->root = path.length() == 1 && (path.at(0) == QLatin1Char('/'));
    221254        }
    222255
     
    244277                             FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED,
    245278                             &that->platform->findBuf, sizeof(that->platform->findBuf),
    246                              &count, FIL_STANDARDL) != NO_ERROR) {
     279                             &count, FIL_STANDARDL) != NO_ERROR ||
     280                (platform->root && platform->filterOutDots() != NO_ERROR)) {
    247281                that->platform->done = true;
    248282            } else {
     
    268302
    269303#ifdef QT_OS2_USE_DOSFINDFIRST
     304
     305// Used to filter out "." and ".." from root to have consistent behavior across
     306// different IFSes (some report them, some don't).
     307APIRET QFSFileEngineIteratorPlatformSpecificData::filterOutDots()
     308{
     309    while ((!seenDot && (seenDot = qstrcmp(findBuf.achName, ".")) == 0) ||
     310           (!seenDotDot && (seenDotDot = qstrcmp(findBuf.achName, "..") == 0))) {
     311        APIRET arc;
     312        ULONG count = 1;
     313        if ((arc = DosFindNext(hdir, &findBuf,
     314                               sizeof(findBuf), &count)) != NO_ERROR) {
     315            DosFindClose(hdir);
     316            hdir = HDIR_CREATE;
     317            done = true;
     318            return arc;
     319        }
     320    }
     321    return NO_ERROR;
     322}
    270323
    271324//static
Note: See TracChangeset for help on using the changeset viewer.