Deleted Added
full compact
telldir.c (8870) telldir.c (69656)
1/*
2 * Copyright (c) 1983, 1993
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

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

24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
1/*
2 * Copyright (c) 1983, 1993
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

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

24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * $FreeBSD: head/lib/libc/gen/telldir.c 69656 2000-12-06 03:15:49Z deischen $
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char sccsid[] = "@(#)telldir.c 8.1 (Berkeley) 6/4/93";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/param.h>
39#include <dirent.h>

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

48#define SINGLEUSE
49
50/*
51 * One of these structures is malloced to describe the current directory
52 * position each time telldir is called. It records the current magic
53 * cookie returned by getdirentries and the offset within the buffer
54 * associated with that return value.
55 */
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37static char sccsid[] = "@(#)telldir.c 8.1 (Berkeley) 6/4/93";
38#endif /* LIBC_SCCS and not lint */
39
40#include <sys/param.h>
41#include <dirent.h>

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

50#define SINGLEUSE
51
52/*
53 * One of these structures is malloced to describe the current directory
54 * position each time telldir is called. It records the current magic
55 * cookie returned by getdirentries and the offset within the buffer
56 * associated with that return value.
57 */
56struct ddloc {
57 struct ddloc *loc_next;/* next structure in list */
58struct _ddloc {
59 LIST_ENTRY(_ddloc) loc_lqe; /* entry in list */
58 long loc_index; /* key associated with structure */
59 long loc_seek; /* magic cookie returned by getdirentries */
60 long loc_loc; /* offset of entry in buffer */
60 long loc_index; /* key associated with structure */
61 long loc_seek; /* magic cookie returned by getdirentries */
62 long loc_loc; /* offset of entry in buffer */
61 const DIR* loc_dirp; /* directory which used this entry */
62};
63
63};
64
64#define NDIRHASH 32 /* Num of hash lists, must be a power of 2 */
65#define LOCHASH(i) ((i)&(NDIRHASH-1))
66
67static long dd_loccnt; /* Index of entry for sequential readdir's */
68static struct ddloc *dd_hash[NDIRHASH]; /* Hash list heads for ddlocs */
69
70/*
71 * return a pointer into a directory
72 */
73long
74telldir(dirp)
65/*
66 * return a pointer into a directory
67 */
68long
69telldir(dirp)
75 const DIR *dirp;
70 DIR *dirp;
76{
71{
77 register int index;
78 register struct ddloc *lp;
72 struct _ddloc *lp;
79
73
80 if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL)
74 if ((lp = (struct _ddloc *)malloc(sizeof(struct _ddloc))) == NULL)
81 return (-1);
75 return (-1);
82 index = dd_loccnt++;
83 lp->loc_index = index;
76 lp->loc_index = dirp->dd_loccnt++;
84 lp->loc_seek = dirp->dd_seek;
85 lp->loc_loc = dirp->dd_loc;
77 lp->loc_seek = dirp->dd_seek;
78 lp->loc_loc = dirp->dd_loc;
86 lp->loc_dirp = dirp;
87 lp->loc_next = dd_hash[LOCHASH(index)];
88 dd_hash[LOCHASH(index)] = lp;
89 return (index);
79 LIST_INSERT_HEAD(&dirp->dd_locq, lp, loc_lqe);
80 return (lp->loc_index);
90}
91
92/*
93 * seek to an entry in a directory.
94 * Only values returned by "telldir" should be passed to seekdir.
95 */
96void
97_seekdir(dirp, loc)
81}
82
83/*
84 * seek to an entry in a directory.
85 * Only values returned by "telldir" should be passed to seekdir.
86 */
87void
88_seekdir(dirp, loc)
98 register DIR *dirp;
89 DIR *dirp;
99 long loc;
100{
90 long loc;
91{
101 register struct ddloc *lp;
102 register struct ddloc **prevlp;
92 struct _ddloc *lp;
103 struct dirent *dp;
104
93 struct dirent *dp;
94
105 prevlp = &dd_hash[LOCHASH(loc)];
106 lp = *prevlp;
107 while (lp != NULL) {
95 LIST_FOREACH(lp, &dirp->dd_locq, loc_lqe) {
108 if (lp->loc_index == loc)
109 break;
96 if (lp->loc_index == loc)
97 break;
110 prevlp = &lp->loc_next;
111 lp = lp->loc_next;
112 }
113 if (lp == NULL)
114 return;
115 if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek)
116 goto found;
117 (void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET);
118 dirp->dd_seek = lp->loc_seek;
119 dirp->dd_loc = 0;
120 while (dirp->dd_loc < lp->loc_loc) {
121 dp = readdir(dirp);
122 if (dp == NULL)
123 break;
124 }
125found:
126#ifdef SINGLEUSE
98 }
99 if (lp == NULL)
100 return;
101 if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek)
102 goto found;
103 (void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET);
104 dirp->dd_seek = lp->loc_seek;
105 dirp->dd_loc = 0;
106 while (dirp->dd_loc < lp->loc_loc) {
107 dp = readdir(dirp);
108 if (dp == NULL)
109 break;
110 }
111found:
112#ifdef SINGLEUSE
127 *prevlp = lp->loc_next;
113 LIST_REMOVE(lp, loc_lqe);
128 free((caddr_t)lp);
129#endif
130}
131
132/*
133 * Reclaim memory for telldir cookies which weren't used.
134 */
135void
136_reclaim_telldir(dirp)
114 free((caddr_t)lp);
115#endif
116}
117
118/*
119 * Reclaim memory for telldir cookies which weren't used.
120 */
121void
122_reclaim_telldir(dirp)
137 register const DIR *dirp;
123 DIR *dirp;
138{
124{
139 register struct ddloc *lp;
140 register struct ddloc **prevlp;
141 int i;
125 struct _ddloc *lp;
126 struct _ddloc *templp;
142
127
143 for (i = 0; i < NDIRHASH; i++) {
144 prevlp = &dd_hash[i];
145 lp = *prevlp;
146 while (lp != NULL) {
147 if (lp->loc_dirp == dirp) {
148 *prevlp = lp->loc_next;
149 free((caddr_t)lp);
150 lp = *prevlp;
151 continue;
152 }
153 prevlp = &lp->loc_next;
154 lp = lp->loc_next;
155 }
128 lp = LIST_FIRST(&dirp->dd_locq);
129 while (lp != NULL) {
130 templp = lp;
131 lp = LIST_NEXT(lp, loc_lqe);
132 free(templp);
156 }
133 }
134 LIST_INIT(&dirp->dd_locq);
157}
135}