diff --git a/src/lib9/dirread.c b/src/lib9/dirread.c index 40fbe3c..6c00dff 100644 --- a/src/lib9/dirread.c +++ b/src/lib9/dirread.c @@ -3,54 +3,46 @@ #include #include #include +#include extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**, char*); -#if defined(__linux__) +#if defined(__DragonFly__) +static inline int d_reclen(struct dirent *de) { return _DIRENT_DIRSIZ(de); } +#else +static inline int d_reclen(struct dirent *de) { return de->d_reclen; } +#endif + static int mygetdents(int fd, struct dirent *buf, int n) { - off_t off; - int nn; + int err, nn; + DIR *dirp; + + /* use to calculate max size of a dirent */ + struct dirent de; + int max_sz = (sizeof de - sizeof de.d_name) + NAME_MAX + 1; + + if ((dirp = fdopendir(dup(fd))) == nil) + return -1; - /* This doesn't match the man page, but it works in Debian with a 2.2 kernel */ - off = p9seek(fd, 0, 1); - nn = getdirentries(fd, (void*)buf, n, &off); + nn = 0; + while(n >= max_sz){ + if ((err = readdir_r(dirp, buf, &buf)) != 0){ + errno = err; + if(nn == 0) + nn = -1; + break; + } + if (buf == nil) + break; + nn += d_reclen(buf); + n -= d_reclen(buf); + buf = ((char*)buf) + d_reclen(buf); + } + closedir(dirp); return nn; } -#elif defined(__APPLE__) -static int -mygetdents(int fd, struct dirent *buf, int n) -{ - long off; - return getdirentries(fd, (void*)buf, n, &off); -} -#elif defined(__FreeBSD__) || defined(__DragonFly__) -static int -mygetdents(int fd, struct dirent *buf, int n) -{ - off_t off; - return getdirentries(fd, (void*)buf, n, &off); -} -#elif defined(__sun__) || defined(__NetBSD__) || defined(__OpenBSD__) -static int -mygetdents(int fd, struct dirent *buf, int n) -{ - return getdents(fd, (void*)buf, n); -} -#elif defined(__AIX__) -static int -mygetdents(int fd, struct dirent *buf, int n) -{ - return getdirent(fd, (void*)buf, n); -} -#endif - -#if defined(__DragonFly__) -static inline int d_reclen(struct dirent *de) { return _DIRENT_DIRSIZ(de); } -#else -static inline int d_reclen(struct dirent *de) { return de->d_reclen; } -#endif static int countde(char *p, int n)