Changeset 2708 for trunk/src/kmk
- Timestamp:
- Nov 21, 2013, 11:26:40 AM (12 years ago)
- File:
-
- 1 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)
Note:
See TracChangeset
for help on using the changeset viewer.