mescc: Mes C Library: Add closedir, opendir, readdir.
[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 /* Read a directory entry from DIRP.  */
36 struct dirent *
37 readdir (DIR *dirp)
38 {
39   struct dirent *dp;
40   int saved_errno = errno;
41
42   do
43     {
44       size_t reclen;
45
46       if (dirp->offset >= dirp->size)
47         {
48           /* We've emptied out our buffer.  Refill it.  */
49
50           size_t maxread;
51           ssize_t bytes;
52
53           maxread = dirp->allocation;
54
55 #if 0
56           off_t base;
57           bytes = __getdirentries (dirp->fd, dirp->data, maxread, &base);
58 #else
59           bytes = getdents (dirp->fd, dirp->data, maxread);
60 #endif
61           if (bytes <= 0)
62             {
63               /* Don't modifiy errno when reaching EOF.  */
64               if (bytes == 0)
65                 errno = saved_errno;
66               dp = 0;
67               break;
68             }
69           dirp->size = (size_t) bytes;
70
71           /* Reset the offset into the buffer.  */
72           dirp->offset = 0;
73         }
74
75       dp = (struct dirent *) &dirp->data[dirp->offset];
76
77       reclen = dp->d_reclen;
78       dirp->offset += reclen;
79       dirp->filepos = dp->d_off;
80
81       /* Skip deleted files.  */
82     } while (dp->d_ino == 0);
83
84   return dp;
85 }