Deleted Added
full compact
fts-compat.c (128946) fts-compat.c (129052)
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>
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 128946 2004-05-05 06:33:00Z kientzle $");
40__FBSDID("$FreeBSD: head/lib/libc/gen/fts-compat.c 129052 2004-05-08 15:09:02Z peadar $");
41
42#include "namespace.h"
43#include <sys/types.h>
44#include <sys/param.h>
45#include <sys/stat.h>
41
42#include "namespace.h"
43#include <sys/types.h>
44#include <sys/param.h>
45#include <sys/stat.h>
46#include <sys/mount.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 *);
47
48#include <dirent.h>
49#include <errno.h>
50#include <fcntl.h>
51#include <fts.h>
52#include <stdlib.h>
53#include <string.h>
54#include <unistd.h>

--- 4 unchanged lines hidden (view full) ---

59static void fts_lfree(FTSENT *);
60static void fts_load(FTS *, FTSENT *);
61static size_t fts_maxarglen(char * const *);
62static void fts_padjust(FTS *, FTSENT *);
63static int fts_palloc(FTS *, size_t);
64static FTSENT *fts_sort(FTS *, FTSENT *, int);
65static u_short fts_stat(FTS *, FTSENT *, int);
66static int fts_safe_changedir(FTS *, FTSENT *, int, char *);
67static int fts_ufslinks(FTS *sp, const FTSENT *ent);
66
67#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
68
69#define CLR(opt) (sp->fts_options &= ~(opt))
70#define ISSET(opt) (sp->fts_options & (opt))
71#define SET(opt) (sp->fts_options |= (opt))
72
73#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
74
75/* fts_build flags */
76#define BCHILD 1 /* fts_children */
77#define BNAMES 2 /* fts_children, names only */
78#define BREAD 3 /* fts_read */
79
68
69#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
70
71#define CLR(opt) (sp->fts_options &= ~(opt))
72#define ISSET(opt) (sp->fts_options & (opt))
73#define SET(opt) (sp->fts_options |= (opt))
74
75#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
76
77/* fts_build flags */
78#define BCHILD 1 /* fts_children */
79#define BNAMES 2 /* fts_children, names only */
80#define BREAD 3 /* fts_read */
81
82/*
83 * Internal representation of FTS, including extra implementation details.
84 * The FTS returned from fts_open is ftsp_fts from this structure, and it's
85 * fts_priv in turn points back to this internal version. i.e. for a given
86 * fts_private *priv: &priv->fts_fts == (FTS *)f == priv->fts_fts.fts_priv
87 */
88struct _fts_private {
89 FTS ftsp_fts;
90 struct statfs ftsp_statfs;
91 dev_t ftsp_dev;
92 int ftsp_linksreliable;
93};
94
95/*
96 * The "FTS_NOSTAT" option can avoid a lot of calls to stat(2) if it knows
97 * that a directory could not possibly have subdirectories. This is decided
98 * by looking at the link count: A subdirectory would increment its parent's
99 * link count by virtue of its own ".." entry.
100 * This assumption only holds for UFS-like filesystems that implement links
101 * and directories this way, so we must punt for others.
102 */
103
104static const char *ufslike_filesystems[] = {
105 "ufs",
106 "nfs",
107 "nfs4",
108 "ext2fs",
109 0
110};
111
80FTS *
81fts_open(argv, options, compar)
82 char * const *argv;
83 int options;
84 int (*compar)(const FTSENT * const *, const FTSENT * const *);
85{
112FTS *
113fts_open(argv, options, compar)
114 char * const *argv;
115 int options;
116 int (*compar)(const FTSENT * const *, const FTSENT * const *);
117{
118 struct _fts_private *priv;
86 FTS *sp;
87 FTSENT *p, *root;
88 int nitems;
89 FTSENT *parent, *tmp;
90 int len;
91
92 /* Options check. */
93 if (options & ~FTS_OPTIONMASK) {
94 errno = EINVAL;
95 return (NULL);
96 }
97
98 /* Allocate/initialize the stream */
119 FTS *sp;
120 FTSENT *p, *root;
121 int nitems;
122 FTSENT *parent, *tmp;
123 int len;
124
125 /* Options check. */
126 if (options & ~FTS_OPTIONMASK) {
127 errno = EINVAL;
128 return (NULL);
129 }
130
131 /* Allocate/initialize the stream */
99 if ((sp = malloc(sizeof(FTS))) == NULL)
132 if ((priv = malloc(sizeof(struct _fts_private))) == NULL)
100 return (NULL);
133 return (NULL);
101 memset(sp, 0, sizeof(FTS));
134 memset(priv, 0, sizeof(struct _fts_private));
135 sp = &priv->ftsp_fts;
102 sp->fts_compar = compar;
103 sp->fts_options = options;
136 sp->fts_compar = compar;
137 sp->fts_options = options;
138 sp->fts_priv = priv;
104
105 /* Shush, GCC. */
106 tmp = NULL;
107
108 /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
109 if (ISSET(FTS_LOGICAL))
110 SET(FTS_NOCHDIR);
111

--- 520 unchanged lines hidden (view full) ---

632 * directory if we're cheating on stat calls, 0 if we're not doing
633 * any stat calls at all, -1 if we're doing stats on everything.
634 */
635 if (type == BNAMES) {
636 nlinks = 0;
637 /* Be quiet about nostat, GCC. */
638 nostat = 0;
639 } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
139
140 /* Shush, GCC. */
141 tmp = NULL;
142
143 /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
144 if (ISSET(FTS_LOGICAL))
145 SET(FTS_NOCHDIR);
146

--- 520 unchanged lines hidden (view full) ---

667 * directory if we're cheating on stat calls, 0 if we're not doing
668 * any stat calls at all, -1 if we're doing stats on everything.
669 */
670 if (type == BNAMES) {
671 nlinks = 0;
672 /* Be quiet about nostat, GCC. */
673 nostat = 0;
674 } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
640 nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
675 if (fts_ufslinks(sp, cur))
676 nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
677 else
678 nlinks = -1;
641 nostat = 1;
642 } else {
643 nlinks = -1;
644 nostat = 0;
645 }
646
647#ifdef notdef
648 (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink);

--- 500 unchanged lines hidden (view full) ---

1149 ret = fchdir(newfd);
1150bail:
1151 oerrno = errno;
1152 if (fd < 0)
1153 (void)_close(newfd);
1154 errno = oerrno;
1155 return (ret);
1156}
679 nostat = 1;
680 } else {
681 nlinks = -1;
682 nostat = 0;
683 }
684
685#ifdef notdef
686 (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink);

--- 500 unchanged lines hidden (view full) ---

1187 ret = fchdir(newfd);
1188bail:
1189 oerrno = errno;
1190 if (fd < 0)
1191 (void)_close(newfd);
1192 errno = oerrno;
1193 return (ret);
1194}
1195
1196/*
1197 * Check if the filesystem for "ent" has UFS-style links.
1198 */
1199static int
1200fts_ufslinks(FTS *sp, const FTSENT *ent)
1201{
1202 struct _fts_private *priv;
1203 const char **cpp;
1204
1205 priv = sp->fts_priv;
1206 /*
1207 * If this node's device is different from the previous, grab
1208 * the filesystem information, and decide on the reliability
1209 * of the link information from this filesystem for stat(2)
1210 * avoidance.
1211 */
1212 if (priv->ftsp_dev != ent->fts_dev) {
1213 if (statfs(ent->fts_path, &priv->ftsp_statfs) != -1) {
1214 priv->ftsp_dev = ent->fts_dev;
1215 priv->ftsp_linksreliable = 0;
1216 for (cpp = ufslike_filesystems; *cpp; cpp++) {
1217 if (strcmp(priv->ftsp_statfs.f_fstypename,
1218 *cpp) == 0) {
1219 priv->ftsp_linksreliable = 1;
1220 break;
1221 }
1222 }
1223 } else {
1224 priv->ftsp_linksreliable = 0;
1225 }
1226 }
1227 return priv->ftsp_linksreliable;
1228}