- Timestamp:
- Nov 21, 2013 10:26:40 AM (11 years ago)
- Location:
- trunk/src
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kmkbuiltin/fts.c
r2546 r2708 127 127 static FTSENT *fts_sort(FTS *, FTSENT *, size_t); 128 128 static u_short fts_stat(FTS *, FTSENT *, int); 129 #ifdef _MSC_VER 130 static u_short fts_stat_dirent(FTS *sp, FTSENT *p, int follow, struct dirent *pDirEnt); 131 #endif 129 132 static int fts_safe_changedir(const FTS *, const FTSENT *, int, 130 133 const char *); 131 134 132 135 #ifdef _MSC_VER 133 #undef HAVE_STRUCT_DIRENT_D_NAMLEN 134 #undef HAVE_FCHDIR 136 # undef HAVE_FCHDIR 135 137 #endif 136 138 … … 387 389 if (chdir(sp->fts_rdir)) 388 390 saved_errno = errno; 389 391 free(sp->fts_rdir); 390 392 sp->fts_rdir = NULL; 391 393 #endif … … 786 788 else 787 789 oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND; 790 #elif defined(_MSC_VER) 791 # define __opendir2(path, flag) birdDirOpenExtraInfo(path) 788 792 #else 789 793 #define __opendir2(path, flag) opendir(path) … … 941 945 } else 942 946 p->fts_accpath = p->fts_name; 947 943 948 /* Stat it. */ 949 #ifdef _MSC_VER 950 p->fts_info = fts_stat_dirent(sp, p, 0, dp); 951 #else 944 952 p->fts_info = fts_stat(sp, p, 0); 953 #endif 945 954 946 955 /* Decrement link count if applicable. */ … … 1012 1021 } 1013 1022 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. */ 1014 1029 static u_short 1015 fts_stat(sp, p, follow) 1016 FTS *sp; 1017 FTSENT *p; 1018 int follow; 1030 fts_stat_dirent(FTS *sp, FTSENT *p, int follow, struct dirent *pDirEnt) 1019 1031 { 1020 1032 FTSENT *t; … … 1030 1042 sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp; 1031 1043 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; 1042 1048 1043 1049 /* 1044 1050 * If doing a logical walk, or application requested FTS_FOLLOW, do 1045 * a stat(2) . If that fails, check for a non-existent symlink. If1046 * 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)) { 1049 1055 if (stat(p->fts_accpath, sbp)) { 1050 1056 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 } 1062 1060 } 1063 1061 … … 1087 1085 if (ino && dev) /** @todo ino emulation on windows... */ 1088 1086 #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 1104 static u_short 1105 fts_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; 1150 err: 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 1089 1179 for (t = p->fts_parent; 1090 1180 t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent) -
trunk/src/lib/nt/ntdir.c
r2702 r2708 92 92 93 93 94 /** 95 * Alternative opendir, with extra stat() info returned by readdir(). 96 */ 97 BirdDir_T *birdDirOpenExtraInfo(const char *pszPath) 98 { 99 return birdDirOpenInternal(pszPath, NULL, 0 /*fMinimalInfo*/); 100 } 101 102 94 103 static int birdDirReadMore(BirdDir_T *pDir) 95 104 { … … 229 238 { 230 239 fSkipEntry = 1; 240 pDir->fHaveData = 0; 231 241 continue; 232 242 } 233 243 234 pEntry->d_ino = 0;235 pEntry->d_s ize = 0;244 memset(&pEntry->d_stat, 0, sizeof(pEntry->d_stat)); 245 pEntry->d_stat.st_mode = S_IFMT; 236 246 pEntry->d_type = DT_UNKNOWN; 237 pEntry->d_dirsymlink = 0;238 247 pEntry->d_reclen = 0; 239 248 pEntry->d_namlen = 0; … … 246 255 } 247 256 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 } 253 295 254 296 default: -
trunk/src/lib/nt/ntdir.h
r2702 r2708 37 37 typedef struct dirent 38 38 { 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; 47 42 /** The record length. */ 48 43 unsigned __int16 d_reclen; 49 44 /** The name length. */ 50 45 unsigned __int16 d_namlen; 46 /** The name type. */ 47 unsigned char d_type; 51 48 /** The name. */ 52 char d_name[512 - 8 - 8 - 1 - 1 - 2 - 2];49 char d_name[512 - sizeof(BirdStat_T) - 2 - 2 - 1]; 53 50 } BirdDirEntry_T; 51 52 #define d_ino d_stat.st_ino; 54 53 55 54 /** @name d_type values. … … 98 97 99 98 BirdDir_T *birdDirOpen(const char *pszPath); 99 BirdDir_T *birdDirOpenExtraInfo(const char *pszPath); 100 100 BirdDirEntry_T *birdDirRead(BirdDir_T *pDir); 101 101 long birdDirTell(BirdDir_T *pDir); -
trunk/src/lib/nt/ntstat.c
r2707 r2708 184 184 185 185 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 */ 193 void 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 186 218 int birdStatHandle(HANDLE hFile, BirdStat_T *pStat, const char *pszPath) 187 219 { … … 394 426 * Convert the data. 395 427 */ 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); 416 429 417 430 /* Get the serial number, reusing the buffer from above. */ -
trunk/src/lib/nt/ntstat.h
r2707 r2708 79 79 int birdStatOnFd(int fd, BirdStat_T *pStat); 80 80 int birdStatModTimeOnly(const char *pszPath, BirdTimeSpec_T *pTimeSpec, int fFollowLink); 81 #ifdef ___nt_ntstuff_h 82 void birdStatFillFromFileIdFullDirInfo(BirdStat_T *pStat, MY_FILE_ID_FULL_DIR_INFORMATION const *pBuf, const char *pszPath); 83 #endif 81 84 82 85 #define STAT_REDEFINED_ALREADY -
trunk/src/lib/nt/ntstuff.h
r2704 r2708 197 197 WCHAR FileName[1]; 198 198 } 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 ) 199 201 200 202
Note:
See TracChangeset
for help on using the changeset viewer.