Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libc / posix / readdir_r.c
blobac55cc8efb1eec85e23d4d925f9b35d2cdc9bb35
1 #ifndef HAVE_OPENDIR
3 /*
4 * Copyright (c) 1983 Regents of the University of California.
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
32 /* this code is modified from readdir.c by Jeff Johnston, June 5, 2002 */
34 #if defined(LIBC_SCCS) && !defined(lint)
35 static char sccsid[] = "@(#)readdir.c 5.7 (Berkeley) 6/1/90";
36 #endif /* LIBC_SCCS and not lint */
38 #include <dirent.h>
39 #include <errno.h>
40 #include <string.h>
41 #include <sys/param.h>
43 extern int getdents (int fd, void *dp, int count);
46 * get next entry in a directory using supplied dirent structure.
48 int
49 readdir_r (register DIR *__restrict dirp,
50 struct dirent *__restrict dp,
51 struct dirent **__restrict dpp) {
53 struct dirent *tmpdp;
55 #ifdef HAVE_DD_LOCK
56 __lock_acquire_recursive(dirp->dd_lock);
57 #endif
59 for (;;) {
60 if (dirp->dd_loc == 0) {
61 dirp->dd_size = getdents (dirp->dd_fd,
62 dirp->dd_buf,
63 dirp->dd_len);
65 if (dirp->dd_size <= 0) {
66 #ifdef HAVE_DD_LOCK
67 __lock_release_recursive(dirp->dd_lock);
68 #endif
69 *dpp = NULL;
70 return dirp->dd_size == 0 ? 0 : errno;
73 if (dirp->dd_loc >= dirp->dd_size) {
74 dirp->dd_loc = 0;
75 continue;
77 tmpdp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc);
79 if (tmpdp->d_reclen <= 0 ||
80 tmpdp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) {
81 #ifdef HAVE_DD_LOCK
82 __lock_release_recursive(dirp->dd_lock);
83 #endif
84 *dpp = NULL;
85 return -1;
87 memcpy (dp, tmpdp, MIN (tmpdp->d_reclen, sizeof (struct dirent)));
89 dirp->dd_loc += dp->d_reclen;
90 if (dp->d_ino == 0)
91 continue;
92 #ifdef HAVE_DD_LOCK
93 __lock_release_recursive(dirp->dd_lock);
94 #endif
95 *dpp = dp;
96 return 0;
100 #endif /* ! HAVE_OPENDIR */