| 459 | : p->fts_pathlen) |
| 460 | |
| 461 | FTSENT* |
| 462 | yfts_read(FTS* sp) { |
| 463 | FTSENT *p, *tmp; |
| 464 | int instr; |
| 465 | char* t; |
| 466 | int saved_errno; |
| 467 | |
| 468 | ClearLastSystemError(); |
| 469 | |
| 470 | /* If finished or unrecoverable error, return NULL. */ |
| 471 | if (sp->fts_cur == nullptr || ISSET(FTS_STOP)) { |
| 472 | return nullptr; |
| 473 | } |
| 474 | |
| 475 | /* Set current node pointer. */ |
| 476 | p = sp->fts_cur; |
| 477 | |
| 478 | /* Save and zero out user instructions. */ |
| 479 | instr = p->fts_instr; |
| 480 | p->fts_instr = FTS_NOINSTR; |
| 481 | |
| 482 | /* Any type of file may be re-visited; re-stat and re-turn. */ |
| 483 | if (instr == FTS_AGAIN) { |
| 484 | p->fts_info = fts_stat(sp, p, 0); |
| 485 | p->fts_type = yfts_type_from_info(p->fts_info); |
| 486 | return (p); |
| 487 | } |
| 488 | |
| 489 | /* |
| 490 | * Following a symlink -- SLNONE test allows application to see |
| 491 | * SLNONE and recover. If indirecting through a symlink, have |
| 492 | * keep a pointer to current location. If unable to get that |
| 493 | * pointer, follow fails. |
| 494 | */ |
| 495 | if (instr == FTS_FOLLOW && |
| 496 | (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) { |
| 497 | p->fts_info = fts_stat(sp, p, 1); |
| 498 | p->fts_type = yfts_type_from_info(p->fts_info); |
| 499 | if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { |
| 500 | if (valid_dird(p->fts_symfd = get_cwdd())) { |
| 501 | p->fts_errno = errno; |
| 502 | p->fts_info = FTS_ERR; |
| 503 | } else { |
| 504 | p->fts_flags |= FTS_SYMFOLLOW; |
| 505 | } |
| 506 | } |
| 507 | return (p); |
| 508 | } |
| 509 | |
| 510 | /* Directory in pre-order. */ |
| 511 | if (p->fts_info == FTS_D) { |
| 512 | /* If skipped or crossed mount point, do post-order visit. */ |
| 513 | if (instr == FTS_SKIP || |
| 514 | (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) { |
| 515 | if (p->fts_flags & FTS_SYMFOLLOW) { |
| 516 | close_dird(p->fts_symfd); |
| 517 | } |
| 518 | if (sp->fts_child) { |