| 676 | } |
| 677 | |
| 678 | FTSENT* |
| 679 | yfts_children(FTS* sp, int instr) |
| 680 | { |
| 681 | FTSENT* p; |
| 682 | dird fd; |
| 683 | if (instr && instr != FTS_NAMEONLY) { |
| 684 | errno = EINVAL; |
| 685 | return nullptr; |
| 686 | } |
| 687 | |
| 688 | /* Set current node pointer. */ |
| 689 | p = sp->fts_cur; |
| 690 | |
| 691 | /* |
| 692 | * Errno set to 0 so user can distinguish empty directory from |
| 693 | * an error. |
| 694 | */ |
| 695 | errno = 0; |
| 696 | |
| 697 | /* Fatal errors stop here. */ |
| 698 | if (ISSET(FTS_STOP)) { |
| 699 | return nullptr; |
| 700 | } |
| 701 | |
| 702 | /* Return logical hierarchy of user's arguments. */ |
| 703 | if (p->fts_info == FTS_INIT) { |
| 704 | return (p->fts_link); |
| 705 | } |
| 706 | |
| 707 | /* |
| 708 | * If not a directory being visited in pre-order, stop here. Could |
| 709 | * allow FTS_DNR, assuming the user has fixed the problem, but the |
| 710 | * same effect is available with FTS_AGAIN. |
| 711 | */ |
| 712 | if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */) { |
| 713 | return nullptr; |
| 714 | } |
| 715 | |
| 716 | /* Free up any previous child list. */ |
| 717 | if (sp->fts_child) { |
| 718 | fts_lfree(sp->fts_child); |
| 719 | } |
| 720 | |
| 721 | if (instr == FTS_NAMEONLY) { |
| 722 | SET(FTS_NAMEONLY); |
| 723 | instr = BNAMES; |
| 724 | } else { |
| 725 | instr = BCHILD; |
| 726 | } |
| 727 | |
| 728 | /* |
| 729 | * If using chdir on a relative path and called BEFORE yfts_read does |
| 730 | * its chdir to the root of a traversal, we can lose -- we need to |
| 731 | * chdir into the subdirectory, and we don't know where the current |
| 732 | * directory is, so we can't get back so that the upcoming chdir by |
| 733 | * yfts_read will work. |
| 734 | */ |
| 735 | if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == LOCSLASH_C || |