OSDN Git Service

hidden_def/hidden_proto: convert all users (I hope) termios split, add some missing...
[uclinux-h8/uClibc.git] / libc / misc / dirent / readdir64_r.c
1 #include <features.h>
2
3 #if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS != 64 
4 #undef _FILE_OFFSET_BITS
5 #define _FILE_OFFSET_BITS   64
6 #endif
7 #ifndef __USE_LARGEFILE64
8 # define __USE_LARGEFILE64      1
9 #endif
10 /* We absolutely do _NOT_ want interfaces silently
11  * renamed under us or very bad things will happen... */
12 #ifdef __USE_FILE_OFFSET64
13 # undef __USE_FILE_OFFSET64
14 #endif
15 #include <errno.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <unistd.h>
19 #include <dirent.h>
20 #include "dirstream.h"
21
22 libc_hidden_proto(memcpy)
23
24 int readdir64_r(DIR *dir, struct dirent64 *entry, struct dirent64 **result)
25 {
26         int ret;
27         ssize_t bytes;
28         struct dirent64 *de;
29
30         if (!dir) {
31             __set_errno(EBADF);
32             return(EBADF);
33         }
34         de = NULL;
35
36         __pthread_mutex_lock(&(dir->dd_lock));
37
38         do {
39             if (dir->dd_size <= dir->dd_nextloc) {
40                 /* read dir->dd_max bytes of directory entries. */
41                 bytes = __getdents64(dir->dd_fd, dir->dd_buf, dir->dd_max);
42                 if (bytes <= 0) {
43                     *result = NULL;
44                     ret = errno;
45                     goto all_done;
46                 }
47                 dir->dd_size = bytes;
48                 dir->dd_nextloc = 0;
49             }
50
51             de = (struct dirent64 *) (((char *) dir->dd_buf) + dir->dd_nextloc);
52
53             /* Am I right? H.J. */
54             dir->dd_nextloc += de->d_reclen;
55
56             /* We have to save the next offset here. */
57             dir->dd_nextoff = de->d_off;
58             /* Skip deleted files.  */
59         } while (de->d_ino == 0);
60
61         if (de == NULL) {
62             *result = NULL;
63         } else {
64             *result = memcpy (entry, de, de->d_reclen);
65         }
66         ret = 0;
67
68 all_done:
69
70         __pthread_mutex_unlock(&(dir->dd_lock));
71         return((de != NULL)? 0 : ret);
72 }