php_scandir.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 7 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2018 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Author: Shane Caraveo <shane@caraveo.com> |
  16. | Ilia Alshanetsky <ilia@prohost.org> |
  17. +----------------------------------------------------------------------+
  18. */
  19. #include "php.h"
  20. #include "php_scandir.h"
  21. #ifdef HAVE_SYS_TYPES_H
  22. #include <sys/types.h>
  23. #endif
  24. #ifdef HAVE_DIRENT_H
  25. #include <dirent.h>
  26. #endif
  27. #ifndef HAVE_SCANDIR
  28. #ifdef PHP_WIN32
  29. #include "win32/param.h"
  30. #include "win32/readdir.h"
  31. #endif
  32. #include <stdlib.h>
  33. #include <search.h>
  34. #endif /* HAVE_SCANDIR */
  35. #ifndef HAVE_ALPHASORT
  36. #ifdef HAVE_STRING_H
  37. #include <string.h>
  38. #endif
  39. PHPAPI int php_alphasort(const struct dirent **a, const struct dirent **b)
  40. {
  41. return strcoll((*a)->d_name,(*b)->d_name);
  42. }
  43. #endif /* HAVE_ALPHASORT */
  44. #ifndef HAVE_SCANDIR
  45. PHPAPI int php_scandir(const char *dirname, struct dirent **namelist[], int (*selector) (const struct dirent *entry), int (*compare) (const struct dirent **a, const struct dirent **b))
  46. {
  47. DIR *dirp = NULL;
  48. struct dirent **vector = NULL;
  49. int vector_size = 0;
  50. int nfiles = 0;
  51. char entry[sizeof(struct dirent)+MAXPATHLEN];
  52. struct dirent *dp = (struct dirent *)&entry;
  53. if (namelist == NULL) {
  54. return -1;
  55. }
  56. if (!(dirp = opendir(dirname))) {
  57. return -1;
  58. }
  59. while (!php_readdir_r(dirp, (struct dirent *)entry, &dp) && dp) {
  60. size_t dsize = 0;
  61. struct dirent *newdp = NULL;
  62. if (selector && (*selector)(dp) == 0) {
  63. continue;
  64. }
  65. if (nfiles == vector_size) {
  66. struct dirent **newv;
  67. if (vector_size == 0) {
  68. vector_size = 10;
  69. } else {
  70. vector_size *= 2;
  71. }
  72. newv = (struct dirent **) realloc (vector, vector_size * sizeof (struct dirent *));
  73. if (!newv) {
  74. return -1;
  75. }
  76. vector = newv;
  77. }
  78. dsize = sizeof (struct dirent) + ((strlen(dp->d_name) + 1) * sizeof(char));
  79. newdp = (struct dirent *) malloc(dsize);
  80. if (newdp == NULL) {
  81. goto fail;
  82. }
  83. vector[nfiles++] = (struct dirent *) memcpy(newdp, dp, dsize);
  84. }
  85. closedir(dirp);
  86. *namelist = vector;
  87. if (compare) {
  88. qsort (*namelist, nfiles, sizeof(struct dirent *), (int (*) (const void *, const void *)) compare);
  89. }
  90. return nfiles;
  91. fail:
  92. while (nfiles-- > 0) {
  93. free(vector[nfiles]);
  94. }
  95. free(vector);
  96. return -1;
  97. }
  98. #endif
  99. /*
  100. * Local variables:
  101. * tab-width: 4
  102. * c-basic-offset: 4
  103. * End:
  104. * vim600: sw=4 ts=4 fdm=marker
  105. * vim<600: sw=4 ts=4
  106. */