grep: Fix various bugs in recursive tree handling
The -OpS options were effectively ignored due to a collection of
bugs in the use of fts(3):
- fts_open(3) requires one of FTS_PHYSICAL or FTS_LOGICAL to be specified, but in the -O case, only FTS_COMFOLLOW was given. Fix this to use FTS_COMFOLLOW | FTS_PHYSICAL.
- The switch on the entry type returned by fts_read() did not check for symbolic links, so symbolic links fell into the default case and were always passed to procfile() even when -p was given. Fix this by adding cases in the switch statement to explicitly ignore FTS_SL.
- FTS_NOSTAT was passed to fts_open(), so fts_open() couldn't detect symbolic links when FTS_PHYSICAL was passed, instead both regular files and symbolic links were returned as FTS_NSOK entries. Fix by only using FTS_NOSTAT with FTS_LOGICAL.
While here, fix a few other nits:
- Treat FTS_NS as an error like FTS_DNR and FTS_ERR.
- Just ignore FTS_DP. The logic to skip descending into skipped directories is only relevant when a directory is first visited, not after the directory has been visited.
- Use warnc instead of warnx + strerror.
PR: 280676
Reviewed by: kevans
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D46255