123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- #include "lib.h"
- #include <stdlib.h>
- #include <sys/stat.h>
- #include <dirent.h>
- #include <unistd.h>
- #include <errno.h>
- #include <string.h>
- #include "sys9.h"
- #include "dir.h"
- #define DBLOCKSIZE 20
- DIR *
- opendir(const char *filename)
- {
- int f;
- DIR *d;
- struct stat sb;
- Dir *d9;
- if((d9 = _dirstat(filename)) == nil){
- _syserrno();
- return NULL;
- }
- _dirtostat(&sb, d9, 0);
- free(d9);
- if(S_ISDIR(sb.st_mode) == 0) {
- errno = ENOTDIR;
- return NULL;
- }
- f = open(filename, O_RDONLY);
- if(f < 0){
- _syserrno();
- return NULL;
- }
- _fdinfo[f].flags |= FD_CLOEXEC;
- d = (DIR *)malloc(sizeof(DIR) + DBLOCKSIZE*sizeof(struct dirent));
- if(!d){
- errno = ENOMEM;
- return NULL;
- }
- d->dd_buf = ((char *)d) + sizeof(DIR);
- d->dd_fd = f;
- d->dd_loc = 0;
- d->dd_size = 0;
- d->dirs = nil;
- d->dirsize = 0;
- d->dirloc = 0;
- return d;
- }
- int
- closedir(DIR *d)
- {
- if(!d){
- errno = EBADF;
- return -1;
- }
- if(close(d->dd_fd) < 0)
- return -1;
- free(d->dirs);
- free(d);
- return 0;
- }
- void
- rewinddir(DIR *d)
- {
- int f;
- char dname[300];
- d->dd_loc = 0;
- d->dd_size = 0;
- d->dirsize = 0;
- d->dirloc = 0;
- free(d->dirs);
- d->dirs = nil;
- if(!d){
- return;
- }
- if(_SEEK(d->dd_fd, 0, 0) < 0){
- _syserrno();
- return;
- }
- }
- struct dirent *
- readdir(DIR *d)
- {
- int i, n;
- struct dirent *dr;
- Dir *dirs;
- if(!d){
- errno = EBADF;
- return NULL;
- }
- if(d->dd_loc >= d->dd_size){
- if(d->dirloc >= d->dirsize){
- free(d->dirs);
- d->dirsize = _dirread(d->dd_fd, &d->dirs);
- d->dirloc = 0;
- }
- if(d->dirs == NULL)
- return NULL;
- dr = (struct dirent *)(d->dd_buf);
- dirs = d->dirs;
- for(i=0; i<DBLOCKSIZE && d->dirloc < d->dirsize; i++){
- strncpy(dr[i].d_name, dirs[d->dirloc++].name, MAXNAMLEN);
- dr[i].d_name[MAXNAMLEN] = 0;
- }
- d->dd_loc = 0;
- d->dd_size = i*sizeof(struct dirent);
- }
- dr = (struct dirent*)(d->dd_buf+d->dd_loc);
- d->dd_loc += sizeof(struct dirent);
- return dr;
- }
|