* Given a file with name "fname", read it (either from disk, or from * an index if 'istate' is non-null), parse it and store the * exclude rules in "pl". * * If "oid_stat" is not NULL, compute oid of the exclude file and fill * stat data from disk (only valid if add_patterns returns zero). If * oid_stat.valid is non-zero, "oid_stat" must contain good value as input. */
| 1147 | * oid_stat.valid is non-zero, "oid_stat" must contain good value as input. |
| 1148 | */ |
| 1149 | static int add_patterns(const char *fname, const char *base, int baselen, |
| 1150 | struct pattern_list *pl, struct index_state *istate, |
| 1151 | unsigned flags, struct oid_stat *oid_stat) |
| 1152 | { |
| 1153 | struct stat st; |
| 1154 | int r; |
| 1155 | int fd; |
| 1156 | size_t size = 0; |
| 1157 | char *buf; |
| 1158 | |
| 1159 | if (flags & PATTERN_NOFOLLOW) |
| 1160 | fd = open_nofollow(fname, O_RDONLY); |
| 1161 | else |
| 1162 | fd = open(fname, O_RDONLY); |
| 1163 | |
| 1164 | if (fd < 0 || fstat(fd, &st) < 0) { |
| 1165 | if (fd < 0) |
| 1166 | warn_on_fopen_errors(fname); |
| 1167 | else |
| 1168 | close(fd); |
| 1169 | if (!istate) |
| 1170 | return -1; |
| 1171 | r = read_skip_worktree_file_from_index(istate, fname, |
| 1172 | &size, &buf, |
| 1173 | oid_stat); |
| 1174 | if (r != 1) |
| 1175 | return r; |
| 1176 | } else { |
| 1177 | size = xsize_t(st.st_size); |
| 1178 | if (size == 0) { |
| 1179 | if (oid_stat) { |
| 1180 | fill_stat_data(&oid_stat->stat, &st); |
| 1181 | oidcpy(&oid_stat->oid, the_hash_algo->empty_blob); |
| 1182 | oid_stat->valid = 1; |
| 1183 | } |
| 1184 | close(fd); |
| 1185 | return 0; |
| 1186 | } |
| 1187 | buf = xmallocz(size); |
| 1188 | if (read_in_full(fd, buf, size) != size) { |
| 1189 | free(buf); |
| 1190 | close(fd); |
| 1191 | return -1; |
| 1192 | } |
| 1193 | buf[size++] = '\n'; |
| 1194 | close(fd); |
| 1195 | if (oid_stat) { |
| 1196 | int pos; |
| 1197 | if (oid_stat->valid && |
| 1198 | !match_stat_data_racy(istate, &oid_stat->stat, &st)) |
| 1199 | ; /* no content change, oid_stat->oid still good */ |
| 1200 | else if (istate && |
| 1201 | (pos = index_name_pos(istate, fname, strlen(fname))) >= 0 && |
| 1202 | !ce_stage(istate->cache[pos]) && |
| 1203 | ce_uptodate(istate->cache[pos]) && |
| 1204 | !would_convert_to_git(istate, fname)) |
| 1205 | oidcpy(&oid_stat->oid, |
| 1206 | &istate->cache[pos]->oid); |
no test coverage detected