mescc: Mes C Library: Support GNU Awk: Implement atof.
[mes.git] / lib / dirent / readdir.c
1 /* -*-comment-start: "//";comment-end:""-*-
2  * GNU Mes --- Maxwell Equations of Software
3  * Copyright (C) 1991,92,93,94,95,96,97,99,2000 Free Software Foundation, Inc.
4  * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
5  *
6  * This file is part of GNU Mes.
7  *
8  * GNU Mes is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or (at
11  * your option) any later version.
12  *
13  * GNU Mes is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 // Taken from GNU C Library 2.2.5
23
24 #include <errno.h>
25 #include <limits.h>
26 #include <stddef.h>
27 #include <string.h>
28 #include <dirent.h>
29 #include <unistd.h>
30 #include <sys/types.h>
31 #include <assert.h>
32
33 #include <dirstream.h>
34
35 int getdents (int filedes, char *buffer, size_t nbytes);
36
37 /* Read a directory entry from DIRP.  */
38 struct dirent *
39 readdir (DIR * dirp)
40 {
41   struct dirent *dp;
42   int saved_errno = errno;
43
44   do
45     {
46       size_t reclen;
47
48       if (dirp->offset >= dirp->size)
49         {
50           /* We've emptied out our buffer.  Refill it.  */
51
52           size_t maxread;
53           ssize_t bytes;
54
55           maxread = dirp->allocation;
56
57 #if 0
58           off_t base;
59           bytes = __getdirentries (dirp->fd, dirp->data, maxread, &base);
60 #else
61           bytes = getdents (dirp->fd, dirp->data, maxread);
62 #endif
63           if (bytes <= 0)
64             {
65               /* Don't modifiy errno when reaching EOF.  */
66               if (bytes == 0)
67                 errno = saved_errno;
68               dp = 0;
69               break;
70             }
71           dirp->size = (size_t) bytes;
72
73           /* Reset the offset into the buffer.  */
74           dirp->offset = 0;
75         }
76
77       dp = (struct dirent *) &dirp->data[dirp->offset];
78
79       reclen = dp->d_reclen;
80       dirp->offset += reclen;
81       dirp->filepos = dp->d_off;
82
83       /* Skip deleted files.  */
84     }
85   while (dp->d_ino == 0);
86
87   return dp;
88 }