Deleted Added
full compact
opendir.c (241046) opendir.c (247236)
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

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

26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char sccsid[] = "@(#)opendir.c 8.8 (Berkeley) 5/1/95";
32#endif /* LIBC_SCCS and not lint */
33#include <sys/cdefs.h>
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

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

26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char sccsid[] = "@(#)opendir.c 8.8 (Berkeley) 5/1/95";
32#endif /* LIBC_SCCS and not lint */
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/lib/libc/gen/opendir.c 241046 2012-09-29 11:54:34Z jilles $");
34__FBSDID("$FreeBSD: head/lib/libc/gen/opendir.c 247236 2013-02-24 20:53:32Z jilles $");
35
36#include "namespace.h"
37#include <sys/param.h>
38#include <sys/mount.h>
39#include <sys/stat.h>
40
41#include <dirent.h>
42#include <errno.h>
43#include <fcntl.h>
44#include <stdlib.h>
45#include <string.h>
46#include <unistd.h>
47#include "un-namespace.h"
48
49#include "gen-private.h"
50#include "telldir.h"
51
35
36#include "namespace.h"
37#include <sys/param.h>
38#include <sys/mount.h>
39#include <sys/stat.h>
40
41#include <dirent.h>
42#include <errno.h>
43#include <fcntl.h>
44#include <stdlib.h>
45#include <string.h>
46#include <unistd.h>
47#include "un-namespace.h"
48
49#include "gen-private.h"
50#include "telldir.h"
51
52static DIR * __opendir_common(int, const char *, int);
52static DIR * __opendir_common(int, int);
53
54/*
55 * Open a directory.
56 */
57DIR *
58opendir(const char *name)
59{
60

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

73 if (_fstat(fd, &statb) != 0)
74 return (NULL);
75 if (!S_ISDIR(statb.st_mode)) {
76 errno = ENOTDIR;
77 return (NULL);
78 }
79 if (_fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
80 return (NULL);
53
54/*
55 * Open a directory.
56 */
57DIR *
58opendir(const char *name)
59{
60

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

73 if (_fstat(fd, &statb) != 0)
74 return (NULL);
75 if (!S_ISDIR(statb.st_mode)) {
76 errno = ENOTDIR;
77 return (NULL);
78 }
79 if (_fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
80 return (NULL);
81 return (__opendir_common(fd, NULL, DTF_HIDEW|DTF_NODUP));
81 return (__opendir_common(fd, DTF_HIDEW|DTF_NODUP));
82}
83
84DIR *
85__opendir2(const char *name, int flags)
86{
87 int fd;
88 DIR *dir;
89 int saved_errno;
90
91 if ((fd = _open(name,
92 O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC)) == -1)
93 return (NULL);
94
82}
83
84DIR *
85__opendir2(const char *name, int flags)
86{
87 int fd;
88 DIR *dir;
89 int saved_errno;
90
91 if ((fd = _open(name,
92 O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC)) == -1)
93 return (NULL);
94
95 dir = __opendir_common(fd, name, flags);
95 dir = __opendir_common(fd, flags);
96 if (dir == NULL) {
97 saved_errno = errno;
98 _close(fd);
99 errno = saved_errno;
100 }
101 return (dir);
102}
103

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

108 return (strcmp((*(const struct dirent **)p1)->d_name,
109 (*(const struct dirent **)p2)->d_name));
110}
111
112/*
113 * Common routine for opendir(3), __opendir2(3) and fdopendir(3).
114 */
115static DIR *
96 if (dir == NULL) {
97 saved_errno = errno;
98 _close(fd);
99 errno = saved_errno;
100 }
101 return (dir);
102}
103

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

108 return (strcmp((*(const struct dirent **)p1)->d_name,
109 (*(const struct dirent **)p2)->d_name));
110}
111
112/*
113 * Common routine for opendir(3), __opendir2(3) and fdopendir(3).
114 */
115static DIR *
116__opendir_common(int fd, const char *name, int flags)
116__opendir_common(int fd, int flags)
117{
118 DIR *dirp;
119 int incr;
120 int saved_errno;
121 int unionstack;
122 int fd2;
123
117{
118 DIR *dirp;
119 int incr;
120 int saved_errno;
121 int unionstack;
122 int fd2;
123
124 fd2 = -1;
125
124 if ((dirp = malloc(sizeof(DIR) + sizeof(struct _telldir))) == NULL)
125 return (NULL);
126
127 dirp->dd_td = (struct _telldir *)((char *)dirp + sizeof(DIR));
128 LIST_INIT(&dirp->dd_td->td_locq);
129 dirp->dd_td->td_loccnt = 0;
130
131 /*

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

160 int n;
161 struct dirent **dpv;
162
163 /*
164 * The strategy here is to read all the directory
165 * entries into a buffer, sort the buffer, and
166 * remove duplicate entries by setting the inode
167 * number to zero.
126 if ((dirp = malloc(sizeof(DIR) + sizeof(struct _telldir))) == NULL)
127 return (NULL);
128
129 dirp->dd_td = (struct _telldir *)((char *)dirp + sizeof(DIR));
130 LIST_INIT(&dirp->dd_td->td_locq);
131 dirp->dd_td->td_loccnt = 0;
132
133 /*

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

162 int n;
163 struct dirent **dpv;
164
165 /*
166 * The strategy here is to read all the directory
167 * entries into a buffer, sort the buffer, and
168 * remove duplicate entries by setting the inode
169 * number to zero.
170 *
171 * We reopen the directory because _getdirentries()
172 * on a MNT_UNION mount modifies the open directory,
173 * making it refer to the lower directory after the
174 * upper directory's entries are exhausted.
175 * This would otherwise break software that uses
176 * the directory descriptor for fchdir or *at
177 * functions, such as fts.c.
168 */
178 */
179 if ((fd2 = _openat(fd, ".", O_RDONLY | O_CLOEXEC)) == -1) {
180 saved_errno = errno;
181 free(buf);
182 free(dirp);
183 errno = saved_errno;
184 return (NULL);
185 }
169
170 do {
171 /*
172 * Always make at least DIRBLKSIZ bytes
173 * available to _getdirentries
174 */
175 if (space < DIRBLKSIZ) {
176 space += incr;
177 len += incr;
178 buf = reallocf(buf, len);
179 if (buf == NULL)
180 goto fail;
181 ddptr = buf + (len - space);
182 }
183
186
187 do {
188 /*
189 * Always make at least DIRBLKSIZ bytes
190 * available to _getdirentries
191 */
192 if (space < DIRBLKSIZ) {
193 space += incr;
194 len += incr;
195 buf = reallocf(buf, len);
196 if (buf == NULL)
197 goto fail;
198 ddptr = buf + (len - space);
199 }
200
184 n = _getdirentries(fd, ddptr, space, &dirp->dd_seek);
201 n = _getdirentries(fd2, ddptr, space, &dirp->dd_seek);
185 if (n > 0) {
186 ddptr += n;
187 space -= n;
188 }
189 } while (n > 0);
190
191 ddeptr = ddptr;
192 flags |= __DTF_READALL;
193
202 if (n > 0) {
203 ddptr += n;
204 space -= n;
205 }
206 } while (n > 0);
207
208 ddeptr = ddptr;
209 flags |= __DTF_READALL;
210
194 /*
195 * Re-open the directory.
196 * This has the effect of rewinding back to the
197 * top of the union stack and is needed by
198 * programs which plan to fchdir to a descriptor
199 * which has also been read -- see fts.c.
200 */
201 if (flags & DTF_REWIND) {
202 if ((fd2 = _open(name, O_RDONLY | O_DIRECTORY |
203 O_CLOEXEC)) == -1) {
204 saved_errno = errno;
205 free(buf);
206 free(dirp);
207 errno = saved_errno;
208 return (NULL);
209 }
210 (void)_dup2(fd2, fd);
211 _close(fd2);
212 }
211 _close(fd2);
212 fd2 = -1;
213
214 /*
215 * There is now a buffer full of (possibly) duplicate
216 * names.
217 */
218 dirp->dd_buf = buf;
219
220 /*

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

288 dirp->dd_size = ddptr - dirp->dd_buf;
289 } else {
290 dirp->dd_len = incr;
291 dirp->dd_size = 0;
292 dirp->dd_buf = malloc(dirp->dd_len);
293 if (dirp->dd_buf == NULL)
294 goto fail;
295 dirp->dd_seek = 0;
213
214 /*
215 * There is now a buffer full of (possibly) duplicate
216 * names.
217 */
218 dirp->dd_buf = buf;
219
220 /*

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

288 dirp->dd_size = ddptr - dirp->dd_buf;
289 } else {
290 dirp->dd_len = incr;
291 dirp->dd_size = 0;
292 dirp->dd_buf = malloc(dirp->dd_len);
293 if (dirp->dd_buf == NULL)
294 goto fail;
295 dirp->dd_seek = 0;
296 flags &= ~DTF_REWIND;
297 }
298
299 dirp->dd_loc = 0;
300 dirp->dd_fd = fd;
301 dirp->dd_flags = flags;
302 dirp->dd_lock = NULL;
303
304 /*
305 * Set up seek point for rewinddir.
306 */
307 dirp->dd_rewind = telldir(dirp);
308
309 return (dirp);
310
311fail:
312 saved_errno = errno;
296 }
297
298 dirp->dd_loc = 0;
299 dirp->dd_fd = fd;
300 dirp->dd_flags = flags;
301 dirp->dd_lock = NULL;
302
303 /*
304 * Set up seek point for rewinddir.
305 */
306 dirp->dd_rewind = telldir(dirp);
307
308 return (dirp);
309
310fail:
311 saved_errno = errno;
312 if (fd2 != -1)
313 _close(fd2);
313 free(dirp);
314 errno = saved_errno;
315 return (NULL);
316}
314 free(dirp);
315 errno = saved_errno;
316 return (NULL);
317}