blob: d08997ffa8783d06d019e825b5abf6df47ecab8e [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*
2 * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
3 *
4 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
5 */
6
7#include <errno.h>
8#include <stdlib.h>
9#include <string.h>
10#include <unistd.h>
11#include <dirent.h>
12#include "dirstream.h"
13
14
15int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result)
16{
17 int ret;
18 ssize_t bytes;
19 struct dirent *de;
20
21 if (!dir) {
22 __set_errno(EBADF);
23 return(EBADF);
24 }
25 de = NULL;
26
27 __UCLIBC_MUTEX_LOCK(dir->dd_lock);
28
29 do {
30 if (dir->dd_size <= dir->dd_nextloc) {
31 /* read dir->dd_max bytes of directory entries. */
32 bytes = __getdents(dir->dd_fd, dir->dd_buf, dir->dd_max);
33 if (bytes <= 0) {
34 *result = NULL;
35 ret = (bytes==0)? 0 : errno;
36 goto all_done;
37 }
38 dir->dd_size = bytes;
39 dir->dd_nextloc = 0;
40 }
41
42 de = (struct dirent *) (((char *) dir->dd_buf) + dir->dd_nextloc);
43
44 /* Am I right? H.J. */
45 dir->dd_nextloc += de->d_reclen;
46
47 /* We have to save the next offset here. */
48 dir->dd_nextoff = de->d_off;
49 /* Skip deleted files. */
50 } while (de->d_ino == 0);
51
52 if (de == NULL) {
53 *result = NULL;
54 } else {
55 *result = memcpy (entry, de, de->d_reclen);
56 }
57 ret = 0;
58
59all_done:
60
61 __UCLIBC_MUTEX_UNLOCK(dir->dd_lock);
62 return((de != NULL)? 0 : ret);
63}
64libc_hidden_def(readdir_r)