readdir64_r.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /*
  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. #include <features.h>
  7. #if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS != 64
  8. #undef _FILE_OFFSET_BITS
  9. #define _FILE_OFFSET_BITS 64
  10. #endif
  11. #ifndef __USE_LARGEFILE64
  12. # define __USE_LARGEFILE64 1
  13. #endif
  14. /* We absolutely do _NOT_ want interfaces silently
  15. * renamed under us or very bad things will happen... */
  16. #ifdef __USE_FILE_OFFSET64
  17. # undef __USE_FILE_OFFSET64
  18. #endif
  19. #include <dirent.h>
  20. #include <errno.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <unistd.h>
  24. #include <dirent.h>
  25. #include "dirstream.h"
  26. libc_hidden_proto(memcpy)
  27. int readdir64_r(DIR *dir, struct dirent64 *entry, struct dirent64 **result)
  28. {
  29. int ret;
  30. ssize_t bytes;
  31. struct dirent64 *de;
  32. if (!dir) {
  33. __set_errno(EBADF);
  34. return(EBADF);
  35. }
  36. de = NULL;
  37. __pthread_mutex_lock(&(dir->dd_lock));
  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. de = (struct dirent64 *) (((char *) dir->dd_buf) + dir->dd_nextloc);
  51. /* Am I right? H.J. */
  52. dir->dd_nextloc += de->d_reclen;
  53. /* We have to save the next offset here. */
  54. dir->dd_nextoff = de->d_off;
  55. /* Skip deleted files. */
  56. } while (de->d_ino == 0);
  57. if (de == NULL) {
  58. *result = NULL;
  59. } else {
  60. *result = memcpy (entry, de, de->d_reclen);
  61. }
  62. ret = 0;
  63. all_done:
  64. __pthread_mutex_unlock(&(dir->dd_lock));
  65. return((de != NULL)? 0 : ret);
  66. }