chiark / gitweb /
[PATCH] sync with latest version of klibc (0.107)
[elogind.git] / klibc / klibc / readdir.c
1 /*
2  * opendir/readdir/closedir
3  */
4
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <stdlib.h>
8 #include <sys/dirent.h>
9 #include <stdio.h>
10
11 #define __IO_DIR_DEFINED
12 struct _IO_dir {
13   int fd;
14   size_t bytes_left;
15   struct dirent *next;
16   struct dirent buffer[15];     /* 15 times max dirent size =~ 4K */
17 };
18
19 #include <dirent.h>
20
21 DIR *opendir(const char *name)
22 {
23   DIR *dp = malloc(sizeof(DIR));
24
25   if ( !dp )
26     return NULL;
27
28   dp->fd = open(name, O_DIRECTORY|O_RDONLY);
29
30   if ( dp->fd < 0 ) {
31     free(dp);
32     return NULL;
33   }
34
35   dp->bytes_left = 0;
36
37   return dp;
38 }
39
40 struct dirent *readdir(DIR *dir)
41 {
42   struct dirent *dent;
43   int rv;
44   
45   if ( !dir->bytes_left ) {
46     rv = getdents(dir->fd, dir->buffer, sizeof(dir->buffer));
47     if ( rv <= 0 )
48       return NULL;
49     dir->bytes_left = rv;
50     dir->next = dir->buffer;
51   }
52
53   dent = dir->next;
54   ((char *)dir->next) += dent->d_reclen;
55   dir->bytes_left -= dent->d_reclen;
56   
57   return dent;
58 }
59
60 int closedir(DIR *dir)
61 {
62   int rv;
63   rv = close(dir->fd);
64   free(dir);
65   return rv;
66 }