VirtualBox

Changeset 2708 in kBuild for trunk/src


Ignore:
Timestamp:
Nov 21, 2013 10:26:40 AM (11 years ago)
Author:
bird
Message:

Optimized ftsfake.c for windows (similar things can be done for OS/2, if we care).

Location:
trunk/src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/kmkbuiltin/fts.c

    r2546 r2708  
    127127static FTSENT   *fts_sort(FTS *, FTSENT *, size_t);
    128128static u_short   fts_stat(FTS *, FTSENT *, int);
     129#ifdef _MSC_VER
     130static u_short   fts_stat_dirent(FTS *sp, FTSENT *p, int follow, struct dirent *pDirEnt);
     131#endif
    129132static int       fts_safe_changedir(const FTS *, const FTSENT *, int,
    130133    const char *);
    131134
    132135#ifdef _MSC_VER
    133 #undef HAVE_STRUCT_DIRENT_D_NAMLEN
    134 #undef HAVE_FCHDIR
     136# undef HAVE_FCHDIR
    135137#endif
    136138
     
    387389                if (chdir(sp->fts_rdir))
    388390                        saved_errno =  errno;
    389         free(sp->fts_rdir);
     391                free(sp->fts_rdir);
    390392                sp->fts_rdir = NULL;
    391393#endif
     
    786788        else
    787789                oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
     790#elif defined(_MSC_VER)
     791# define __opendir2(path, flag) birdDirOpenExtraInfo(path)
    788792#else
    789793#define __opendir2(path, flag) opendir(path)
     
    941945                        } else
    942946                                p->fts_accpath = p->fts_name;
     947
    943948                        /* Stat it. */
     949#ifdef _MSC_VER
     950                        p->fts_info = fts_stat_dirent(sp, p, 0, dp);
     951#else
    944952                        p->fts_info = fts_stat(sp, p, 0);
     953#endif
    945954
    946955                        /* Decrement link count if applicable. */
     
    10121021}
    10131022
     1023#ifdef _MSC_VER
     1024/** Special version of fts_stat that takes the information from the directory
     1025 *  entry returned by readdir().
     1026 *
     1027 *  Directory listing returns all the stat information on systems likes
     1028 *  Windows and OS/2. */
    10141029static u_short
    1015 fts_stat(sp, p, follow)
    1016         FTS *sp;
    1017         FTSENT *p;
    1018         int follow;
     1030fts_stat_dirent(FTS *sp, FTSENT *p, int follow, struct dirent *pDirEnt)
    10191031{
    10201032        FTSENT *t;
     
    10301042        sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;
    10311043
    1032 #ifdef FTS_WHITEOUT
    1033         /* check for whiteout */
    1034         if (p->fts_flags & FTS_ISW) {
    1035                 if (sbp != &sb) {
    1036                         memset(sbp, '\0', sizeof (*sbp));
    1037                         sbp->st_mode = S_IFWHT;
    1038                 }
    1039                 return (FTS_W);
    1040         }
    1041 #endif
     1044        /*
     1045         * Copy over the stat info from the direntry.
     1046         */
     1047        *sbp = pDirEnt->d_stat;
    10421048
    10431049        /*
    10441050         * If doing a logical walk, or application requested FTS_FOLLOW, do
    1045          * a stat(2).  If that fails, check for a non-existent symlink.  If
    1046          * fail, set the errno from the stat call.
    1047          */
    1048         if (ISSET(FTS_LOGICAL) || follow) {
     1051         * a stat(2) on symlinks.  If that fails, assume non-existent
     1052         * symlink and set the errno from the stat call.
     1053         */
     1054        if (S_ISLNK(sbp->st_mode) && (ISSET(FTS_LOGICAL) || follow)) {
    10491055                if (stat(p->fts_accpath, sbp)) {
    10501056                        saved_errno = errno;
    1051                         if (!lstat(p->fts_accpath, sbp)) {
    1052                                 errno = 0;
    1053                                 return (FTS_SLNONE);
    1054                         }
    1055                         p->fts_errno = saved_errno;
    1056                         goto err;
    1057                 }
    1058         } else if (lstat(p->fts_accpath, sbp)) {
    1059                 p->fts_errno = errno;
    1060 err:            memset(sbp, 0, sizeof(struct STAT));
    1061                 return (FTS_NS);
     1057                        errno = 0;
     1058                        return (FTS_SLNONE);
     1059                }
    10621060        }
    10631061
     
    10871085                if (ino && dev) /** @todo ino emulation on windows... */
    10881086#endif
     1087                    for (t = p->fts_parent;
     1088                        t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
     1089                            if (ino == t->fts_ino && dev == t->fts_dev) {
     1090                                    p->fts_cycle = t;
     1091                                    return (FTS_DC);
     1092                            }
     1093                return (FTS_D);
     1094        }
     1095        if (S_ISLNK(sbp->st_mode))
     1096                return (FTS_SL);
     1097        if (S_ISREG(sbp->st_mode))
     1098                return (FTS_F);
     1099        return (FTS_DEFAULT);
     1100}
     1101
     1102#endif /* fts_stat_dirent */
     1103
     1104static u_short
     1105fts_stat(sp, p, follow)
     1106        FTS *sp;
     1107        FTSENT *p;
     1108        int follow;
     1109{
     1110        FTSENT *t;
     1111        dev_t dev;
     1112        ino_t ino;
     1113        struct STAT *sbp, sb;
     1114        int saved_errno;
     1115
     1116        _DIAGASSERT(sp != NULL);
     1117        _DIAGASSERT(p != NULL);
     1118
     1119        /* If user needs stat info, stat buffer already allocated. */
     1120        sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;
     1121
     1122#ifdef FTS_WHITEOUT
     1123        /* check for whiteout */
     1124        if (p->fts_flags & FTS_ISW) {
     1125                if (sbp != &sb) {
     1126                        memset(sbp, '\0', sizeof (*sbp));
     1127                        sbp->st_mode = S_IFWHT;
     1128                }
     1129                return (FTS_W);
     1130        }
     1131#endif
     1132
     1133        /*
     1134         * If doing a logical walk, or application requested FTS_FOLLOW, do
     1135         * a stat(2).  If that fails, check for a non-existent symlink.  If
     1136         * fail, set the errno from the stat call.
     1137         */
     1138        if (ISSET(FTS_LOGICAL) || follow) {
     1139                if (stat(p->fts_accpath, sbp)) {
     1140                        saved_errno = errno;
     1141                        if (!lstat(p->fts_accpath, sbp)) {
     1142                                errno = 0;
     1143                                return (FTS_SLNONE);
     1144                        }
     1145                        p->fts_errno = saved_errno;
     1146                        goto err;
     1147                }
     1148        } else if (lstat(p->fts_accpath, sbp)) {
     1149                p->fts_errno = errno;
     1150err:            memset(sbp, 0, sizeof(struct STAT));
     1151                return (FTS_NS);
     1152        }
     1153
     1154        if (S_ISDIR(sbp->st_mode)) {
     1155                /*
     1156                 * Set the device/inode.  Used to find cycles and check for
     1157                 * crossing mount points.  Also remember the link count, used
     1158                 * in fts_build to limit the number of stat calls.  It is
     1159                 * understood that these fields are only referenced if fts_info
     1160                 * is set to FTS_D.
     1161                 */
     1162                dev = p->fts_dev = sbp->st_dev;
     1163                ino = p->fts_ino = sbp->st_ino;
     1164                p->fts_nlink = sbp->st_nlink;
     1165
     1166                if (ISDOT(p->fts_name))
     1167                        return (FTS_DOT);
     1168
     1169                /*
     1170                 * Cycle detection is done by brute force when the directory
     1171                 * is first encountered.  If the tree gets deep enough or the
     1172                 * number of symbolic links to directories is high enough,
     1173                 * something faster might be worthwhile.
     1174                 */
     1175
     1176#ifdef _MSC_VER
     1177                if (ino && dev) /** @todo ino emulation on windows... */
     1178#endif
    10891179                for (t = p->fts_parent;
    10901180                    t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
  • trunk/src/lib/nt/ntdir.c

    r2702 r2708  
    9292
    9393
     94/**
     95 * Alternative opendir, with extra stat() info returned by readdir().
     96 */
     97BirdDir_T *birdDirOpenExtraInfo(const char *pszPath)
     98{
     99    return birdDirOpenInternal(pszPath, NULL, 0 /*fMinimalInfo*/);
     100}
     101
     102
    94103static int birdDirReadMore(BirdDir_T *pDir)
    95104{
     
    229238                {
    230239                    fSkipEntry = 1;
     240                    pDir->fHaveData = 0;
    231241                    continue;
    232242                }
    233243
    234                 pEntry->d_ino           = 0;
    235                 pEntry->d_size          = 0;
     244                memset(&pEntry->d_stat, 0, sizeof(pEntry->d_stat));
     245                pEntry->d_stat.st_mode  = S_IFMT;
    236246                pEntry->d_type          = DT_UNKNOWN;
    237                 pEntry->d_dirsymlink    = 0;
    238247                pEntry->d_reclen        = 0;
    239248                pEntry->d_namlen        = 0;
     
    246255            }
    247256
    248             //case MyFileIdBothDirectoryInformation:
    249             //{
    250             //    MY_FILE_BOTH_DIR_INFORMATION
    251             //
    252             //}
     257            case MyFileIdFullDirectoryInformation:
     258            {
     259                MY_FILE_ID_FULL_DIR_INFORMATION *pInfo = (MY_FILE_ID_FULL_DIR_INFORMATION *)&pDir->pabBuf[pDir->offBuf];
     260                if (   pDir->offBuf          >= pDir->cbBuf - MIN_SIZEOF_MY_FILE_ID_FULL_DIR_INFORMATION
     261                    || pInfo->FileNameLength >= pDir->cbBuf
     262                    || pDir->offBuf + pInfo->FileNameLength + MIN_SIZEOF_MY_FILE_ID_FULL_DIR_INFORMATION > pDir->cbBuf)
     263                {
     264                    fSkipEntry = 1;
     265                    pDir->fHaveData = 0;
     266                    continue;
     267                }
     268
     269                pEntry->d_type          = DT_UNKNOWN;
     270                pEntry->d_reclen        = 0;
     271                pEntry->d_namlen        = 0;
     272                if (birdDirCopyNameToEntry(pInfo->FileName, pInfo->FileNameLength, pEntry) != 0)
     273                    fSkipEntry = 1;
     274                birdStatFillFromFileIdFullDirInfo(&pEntry->d_stat, pInfo, pEntry->d_name);
     275                pEntry->d_stat.st_dev   = pDir->uDev;
     276                switch (pEntry->d_stat.st_mode & S_IFMT)
     277                {
     278                    case S_IFREG:       pEntry->d_type = DT_REG; break;
     279                    case S_IFDIR:       pEntry->d_type = DT_DIR; break;
     280                    case S_IFLNK:       pEntry->d_type = DT_LNK; break;
     281                    case S_IFIFO:       pEntry->d_type = DT_FIFO; break;
     282                    case S_IFCHR:       pEntry->d_type = DT_CHR; break;
     283                    default:
     284#ifndef NDEBUG
     285                        __debugbreak();
     286#endif
     287                        pEntry->d_type = DT_UNKNOWN;
     288                        break;
     289                }
     290
     291                cbMinCur = MIN_SIZEOF_MY_FILE_ID_FULL_DIR_INFORMATION + pInfo->FileNameLength;
     292                offNext  = pInfo->NextEntryOffset;
     293                break;
     294            }
    253295
    254296            default:
  • trunk/src/lib/nt/ntdir.h

    r2702 r2708  
    3737typedef struct dirent
    3838{
    39     /** File ID if available. */
    40     unsigned __int64    d_ino;
    41     /** The file size. */
    42     unsigned __int64    d_size;
    43     /** The name type. */
    44     unsigned char       d_type;
    45     /** Qualifies the DT_LNK d_type value. */
    46     unsigned char       d_dirsymlink;
     39    /** Optional stat information.
     40     * Only provided if using birdDirOpenExtraInfo(). */
     41    BirdStat_T          d_stat;
    4742    /** The record length. */
    4843    unsigned __int16    d_reclen;
    4944    /** The name length. */
    5045    unsigned __int16    d_namlen;
     46    /** The name type. */
     47    unsigned char       d_type;
    5148    /** The name. */
    52     char                d_name[512 - 8 - 8 - 1 - 1 - 2 - 2];
     49    char                d_name[512 - sizeof(BirdStat_T) - 2 - 2 - 1];
    5350} BirdDirEntry_T;
     51
     52#define d_ino           d_stat.st_ino;
    5453
    5554/** @name d_type values.
     
    9897
    9998BirdDir_T      *birdDirOpen(const char *pszPath);
     99BirdDir_T      *birdDirOpenExtraInfo(const char *pszPath);
    100100BirdDirEntry_T *birdDirRead(BirdDir_T *pDir);
    101101long            birdDirTell(BirdDir_T *pDir);
  • trunk/src/lib/nt/ntstat.c

    r2707 r2708  
    184184
    185185
     186/**
     187 * Fills in a stat structure from an MY_FILE_ID_FULL_DIR_INFORMATION entry.
     188 *
     189 * @param   pStat               The stat structure.
     190 * @param   pBuf                The MY_FILE_ID_FULL_DIR_INFORMATION entry.
     191 * @param   pszPath             Optionally, the path for X bit checks.
     192 */
     193void birdStatFillFromFileIdFullDirInfo(BirdStat_T *pStat, MY_FILE_ID_FULL_DIR_INFORMATION const *pBuf, const char *pszPath)
     194{
     195    pStat->st_mode          = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes, pszPath,
     196                                                 NULL, &pStat->st_dirsymlink);
     197    pStat->st_padding0[0]   = 0;
     198    pStat->st_padding0[1]   = 0;
     199    pStat->st_size          = pBuf->EndOfFile.QuadPart;
     200    birdNtTimeToTimeSpec(pBuf->CreationTime.QuadPart,   &pStat->st_birthtim);
     201    birdNtTimeToTimeSpec(pBuf->ChangeTime.QuadPart,     &pStat->st_ctim);
     202    birdNtTimeToTimeSpec(pBuf->LastWriteTime.QuadPart,  &pStat->st_mtim);
     203    birdNtTimeToTimeSpec(pBuf->LastAccessTime.QuadPart, &pStat->st_atim);
     204    pStat->st_ino           = pBuf->FileId.QuadPart;
     205    pStat->st_nlink         = 1;
     206    pStat->st_rdev          = 0;
     207    pStat->st_uid           = 0;
     208    pStat->st_gid           = 0;
     209    pStat->st_padding1[0]   = 0;
     210    pStat->st_padding1[1]   = 0;
     211    pStat->st_padding1[2]   = 0;
     212    pStat->st_blksize       = 65536;
     213    pStat->st_blocks        = (pBuf->AllocationSize.QuadPart + BIRD_STAT_BLOCK_SIZE - 1)
     214                            / BIRD_STAT_BLOCK_SIZE;
     215}
     216
     217
    186218int birdStatHandle(HANDLE hFile, BirdStat_T *pStat, const char *pszPath)
    187219{
     
    394426                     * Convert the data.
    395427                     */
    396                     pStat->st_mode          = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes, pszPath,
    397                                                                  NULL, &pStat->st_dirsymlink);
    398                     pStat->st_padding0[0]   = 0;
    399                     pStat->st_padding0[1]   = 0;
    400                     pStat->st_size          = pBuf->EndOfFile.QuadPart;
    401                     birdNtTimeToTimeSpec(pBuf->CreationTime.QuadPart,   &pStat->st_birthtim);
    402                     birdNtTimeToTimeSpec(pBuf->ChangeTime.QuadPart,     &pStat->st_ctim);
    403                     birdNtTimeToTimeSpec(pBuf->LastWriteTime.QuadPart,  &pStat->st_mtim);
    404                     birdNtTimeToTimeSpec(pBuf->LastAccessTime.QuadPart, &pStat->st_atim);
    405                     pStat->st_ino           = pBuf->FileId.QuadPart;
    406                     pStat->st_nlink         = 1;
    407                     pStat->st_rdev          = 0;
    408                     pStat->st_uid           = 0;
    409                     pStat->st_gid           = 0;
    410                     pStat->st_padding1[0]   = 0;
    411                     pStat->st_padding1[1]   = 0;
    412                     pStat->st_padding1[2]   = 0;
    413                     pStat->st_blksize       = 65536;
    414                     pStat->st_blocks        = (pBuf->AllocationSize.QuadPart + BIRD_STAT_BLOCK_SIZE - 1)
    415                                             / BIRD_STAT_BLOCK_SIZE;
     428                    birdStatFillFromFileIdFullDirInfo(pStat, pBuf, pszPath);
    416429
    417430                    /* Get the serial number, reusing the buffer from above. */
  • trunk/src/lib/nt/ntstat.h

    r2707 r2708  
    7979int birdStatOnFd(int fd, BirdStat_T *pStat);
    8080int birdStatModTimeOnly(const char *pszPath, BirdTimeSpec_T *pTimeSpec, int fFollowLink);
     81#ifdef ___nt_ntstuff_h
     82void birdStatFillFromFileIdFullDirInfo(BirdStat_T *pStat, MY_FILE_ID_FULL_DIR_INFORMATION const *pBuf, const char *pszPath);
     83#endif
    8184
    8285#define STAT_REDEFINED_ALREADY
  • trunk/src/lib/nt/ntstuff.h

    r2704 r2708  
    197197    WCHAR           FileName[1];
    198198} MY_FILE_ID_FULL_DIR_INFORMATION;
     199/** The sizeof(MY_FILE_NAMES_INFORMATION) without the FileName. */
     200#define MIN_SIZEOF_MY_FILE_ID_FULL_DIR_INFORMATION  ( (size_t)&((MY_FILE_ID_FULL_DIR_INFORMATION *)0)->FileName )
    199201
    200202
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette