opendir.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include "lib.h"
  2. #include <stdlib.h>
  3. #include <sys/stat.h>
  4. #include <dirent.h>
  5. #include <unistd.h>
  6. #include <errno.h>
  7. #include <string.h>
  8. #include "sys9.h"
  9. #include "dir.h"
  10. #define DBLOCKSIZE 20
  11. DIR *
  12. opendir(const char *filename)
  13. {
  14. int f;
  15. DIR *d;
  16. struct stat sb;
  17. Dir *d9;
  18. if((d9 = _dirstat(filename)) == nil){
  19. _syserrno();
  20. return NULL;
  21. }
  22. _dirtostat(&sb, d9, 0);
  23. free(d9);
  24. if(S_ISDIR(sb.st_mode) == 0) {
  25. errno = ENOTDIR;
  26. return NULL;
  27. }
  28. f = open(filename, O_RDONLY);
  29. if(f < 0){
  30. _syserrno();
  31. return NULL;
  32. }
  33. _fdinfo[f].flags |= FD_CLOEXEC;
  34. d = (DIR *)malloc(sizeof(DIR) + DBLOCKSIZE*sizeof(struct dirent));
  35. if(!d){
  36. errno = ENOMEM;
  37. return NULL;
  38. }
  39. d->dd_buf = ((char *)d) + sizeof(DIR);
  40. d->dd_fd = f;
  41. d->dd_loc = 0;
  42. d->dd_size = 0;
  43. d->dirs = nil;
  44. d->dirsize = 0;
  45. d->dirloc = 0;
  46. return d;
  47. }
  48. int
  49. closedir(DIR *d)
  50. {
  51. if(!d){
  52. errno = EBADF;
  53. return -1;
  54. }
  55. if(close(d->dd_fd) < 0)
  56. return -1;
  57. free(d->dirs);
  58. free(d);
  59. return 0;
  60. }
  61. void
  62. rewinddir(DIR *d)
  63. {
  64. int f;
  65. char dname[300];
  66. d->dd_loc = 0;
  67. d->dd_size = 0;
  68. d->dirsize = 0;
  69. d->dirloc = 0;
  70. free(d->dirs);
  71. d->dirs = nil;
  72. if(!d){
  73. return;
  74. }
  75. if(_SEEK(d->dd_fd, 0, 0) < 0){
  76. _syserrno();
  77. return;
  78. }
  79. }
  80. struct dirent *
  81. readdir(DIR *d)
  82. {
  83. int i, n;
  84. struct dirent *dr;
  85. Dir *dirs;
  86. if(!d){
  87. errno = EBADF;
  88. return NULL;
  89. }
  90. if(d->dd_loc >= d->dd_size){
  91. if(d->dirloc >= d->dirsize){
  92. free(d->dirs);
  93. d->dirsize = _dirread(d->dd_fd, &d->dirs);
  94. d->dirloc = 0;
  95. }
  96. if(d->dirs == NULL)
  97. return NULL;
  98. dr = (struct dirent *)(d->dd_buf);
  99. dirs = d->dirs;
  100. for(i=0; i<DBLOCKSIZE && d->dirloc < d->dirsize; i++){
  101. strncpy(dr[i].d_name, dirs[d->dirloc++].name, MAXNAMLEN);
  102. dr[i].d_name[MAXNAMLEN] = 0;
  103. }
  104. d->dd_loc = 0;
  105. d->dd_size = i*sizeof(struct dirent);
  106. }
  107. dr = (struct dirent*)(d->dd_buf+d->dd_loc);
  108. d->dd_loc += sizeof(struct dirent);
  109. return dr;
  110. }