Deleted Added
full compact
40c40
< __FBSDID("$FreeBSD: head/lib/libc/gen/fts-compat.c 128946 2004-05-05 06:33:00Z kientzle $");
---
> __FBSDID("$FreeBSD: head/lib/libc/gen/fts-compat.c 129052 2004-05-08 15:09:02Z peadar $");
45a46
> #include <sys/mount.h>
65a67
> static int fts_ufslinks(FTS *sp, const FTSENT *ent);
79a82,111
> /*
> * Internal representation of FTS, including extra implementation details.
> * The FTS returned from fts_open is ftsp_fts from this structure, and it's
> * fts_priv in turn points back to this internal version. i.e. for a given
> * fts_private *priv: &priv->fts_fts == (FTS *)f == priv->fts_fts.fts_priv
> */
> struct _fts_private {
> FTS ftsp_fts;
> struct statfs ftsp_statfs;
> dev_t ftsp_dev;
> int ftsp_linksreliable;
> };
>
> /*
> * The "FTS_NOSTAT" option can avoid a lot of calls to stat(2) if it knows
> * that a directory could not possibly have subdirectories. This is decided
> * by looking at the link count: A subdirectory would increment its parent's
> * link count by virtue of its own ".." entry.
> * This assumption only holds for UFS-like filesystems that implement links
> * and directories this way, so we must punt for others.
> */
>
> static const char *ufslike_filesystems[] = {
> "ufs",
> "nfs",
> "nfs4",
> "ext2fs",
> 0
> };
>
85a118
> struct _fts_private *priv;
99c132
< if ((sp = malloc(sizeof(FTS))) == NULL)
---
> if ((priv = malloc(sizeof(struct _fts_private))) == NULL)
101c134,135
< memset(sp, 0, sizeof(FTS));
---
> memset(priv, 0, sizeof(struct _fts_private));
> sp = &priv->ftsp_fts;
103a138
> sp->fts_priv = priv;
640c675,678
< nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
---
> if (fts_ufslinks(sp, cur))
> nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
> else
> nlinks = -1;
1156a1195,1228
>
> /*
> * Check if the filesystem for "ent" has UFS-style links.
> */
> static int
> fts_ufslinks(FTS *sp, const FTSENT *ent)
> {
> struct _fts_private *priv;
> const char **cpp;
>
> priv = sp->fts_priv;
> /*
> * If this node's device is different from the previous, grab
> * the filesystem information, and decide on the reliability
> * of the link information from this filesystem for stat(2)
> * avoidance.
> */
> if (priv->ftsp_dev != ent->fts_dev) {
> if (statfs(ent->fts_path, &priv->ftsp_statfs) != -1) {
> priv->ftsp_dev = ent->fts_dev;
> priv->ftsp_linksreliable = 0;
> for (cpp = ufslike_filesystems; *cpp; cpp++) {
> if (strcmp(priv->ftsp_statfs.f_fstypename,
> *cpp) == 0) {
> priv->ftsp_linksreliable = 1;
> break;
> }
> }
> } else {
> priv->ftsp_linksreliable = 0;
> }
> }
> return priv->ftsp_linksreliable;
> }