1/*- 2 * Copyright (c) 1990, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 23 unchanged lines hidden (view full) --- 32 * 33 * $OpenBSD: fts.c,v 1.22 1999/10/03 19:22:22 millert Exp $ 34 */ 35 36#if defined(LIBC_SCCS) && !defined(lint) 37static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94"; 38#endif /* LIBC_SCCS and not lint */ 39#include <sys/cdefs.h> |
40__FBSDID("$FreeBSD: head/lib/libc/gen/fts-compat.c 129161 2004-05-12 21:38:39Z peadar $"); |
41 42#include "namespace.h" |
43#include <sys/param.h> |
44#include <sys/mount.h> |
45#include <sys/stat.h> |
46 47#include <dirent.h> 48#include <errno.h> 49#include <fcntl.h> 50#include <fts.h> 51#include <stdlib.h> 52#include <string.h> 53#include <unistd.h> --- 4 unchanged lines hidden (view full) --- 58static void fts_lfree(FTSENT *); 59static void fts_load(FTS *, FTSENT *); 60static size_t fts_maxarglen(char * const *); 61static void fts_padjust(FTS *, FTSENT *); 62static int fts_palloc(FTS *, size_t); 63static FTSENT *fts_sort(FTS *, FTSENT *, int); 64static u_short fts_stat(FTS *, FTSENT *, int); 65static int fts_safe_changedir(FTS *, FTSENT *, int, char *); |
66static int fts_ufslinks(FTS *, const FTSENT *); |
67 68#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) 69 70#define CLR(opt) (sp->fts_options &= ~(opt)) 71#define ISSET(opt) (sp->fts_options & (opt)) 72#define SET(opt) (sp->fts_options |= (opt)) 73 74#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd)) 75 76/* fts_build flags */ 77#define BCHILD 1 /* fts_children */ 78#define BNAMES 2 /* fts_children, names only */ 79#define BREAD 3 /* fts_read */ 80 81/* |
82 * Internal representation of an FTS, including extra implementation 83 * details. The FTS returned from fts_open points to this structure's 84 * ftsp_fts member (and can be cast to an _fts_private as required) |
85 */ 86struct _fts_private { |
87 FTS ftsp_fts; 88 struct statfs ftsp_statfs; 89 dev_t ftsp_dev; 90 int ftsp_linksreliable; |
91}; 92 93/* |
94 * The "FTS_NOSTAT" option can avoid a lot of calls to stat(2) if it 95 * knows that a directory could not possibly have subdirectories. This 96 * is decided by looking at the link count: a subdirectory would 97 * increment its parent's link count by virtue of its own ".." entry. 98 * This assumption only holds for UFS-like filesystems that implement 99 * links and directories this way, so we must punt for others. |
100 */ 101 102static const char *ufslike_filesystems[] = { 103 "ufs", 104 "nfs", 105 "nfs4", 106 "ext2fs", 107 0 --- 14 unchanged lines hidden (view full) --- 122 123 /* Options check. */ 124 if (options & ~FTS_OPTIONMASK) { 125 errno = EINVAL; 126 return (NULL); 127 } 128 129 /* Allocate/initialize the stream */ |
130 if ((priv = malloc(sizeof(*priv))) == NULL) |
131 return (NULL); |
132 memset(priv, 0, sizeof(*priv)); |
133 sp = &priv->ftsp_fts; 134 sp->fts_compar = compar; 135 sp->fts_options = options; |
136 137 /* Shush, GCC. */ 138 tmp = NULL; 139 140 /* Logical walks turn on NOCHDIR; symbolic links are too hard. */ 141 if (ISSET(FTS_LOGICAL)) 142 SET(FTS_NOCHDIR); 143 --- 1050 unchanged lines hidden (view full) --- 1194 * Check if the filesystem for "ent" has UFS-style links. 1195 */ 1196static int 1197fts_ufslinks(FTS *sp, const FTSENT *ent) 1198{ 1199 struct _fts_private *priv; 1200 const char **cpp; 1201 |
1202 priv = (struct _fts_private *)sp; |
1203 /* 1204 * If this node's device is different from the previous, grab 1205 * the filesystem information, and decide on the reliability 1206 * of the link information from this filesystem for stat(2) 1207 * avoidance. 1208 */ 1209 if (priv->ftsp_dev != ent->fts_dev) { 1210 if (statfs(ent->fts_path, &priv->ftsp_statfs) != -1) { --- 5 unchanged lines hidden (view full) --- 1216 priv->ftsp_linksreliable = 1; 1217 break; 1218 } 1219 } 1220 } else { 1221 priv->ftsp_linksreliable = 0; 1222 } 1223 } |
1224 return (priv->ftsp_linksreliable); |
1225} |