From a4f07581502ee212aa45e7b0049fdd126dd10b40 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Sat, 11 May 2002 00:26:15 +0000 Subject: Implement readdir_r. Audit for proper thread safety and locking. -Erik --- libc/misc/dirent/readdir_r.c | 63 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 libc/misc/dirent/readdir_r.c (limited to 'libc/misc/dirent/readdir_r.c') diff --git a/libc/misc/dirent/readdir_r.c b/libc/misc/dirent/readdir_r.c new file mode 100644 index 000000000..9d9db0dee --- /dev/null +++ b/libc/misc/dirent/readdir_r.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include "dirstream.h" + +extern int getdents __P ((unsigned int fd, struct dirent *dirp, unsigned int count)); + + +int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result) +{ + int ret; + ssize_t bytes; + struct dirent *de; + + if (!dir) { + __set_errno(EBADF); + return(EBADF); + } + de = NULL; + +#ifdef _POSIX_THREADS + pthread_mutex_lock(dir->dd_lock); +#endif + + do { + if (dir->dd_size <= dir->dd_nextloc) { + /* read dir->dd_max bytes of directory entries. */ + bytes = getdents(dir->dd_fd, dir->dd_buf, dir->dd_max); + if (bytes <= 0) { + *result = NULL; + ret = errno; + goto all_done; + } + dir->dd_size = bytes; + dir->dd_nextloc = 0; + } + + de = (struct dirent *) (((char *) dir->dd_buf) + dir->dd_nextloc); + + /* Am I right? H.J. */ + dir->dd_nextloc += de->d_reclen; + + /* We have to save the next offset here. */ + dir->dd_nextoff = de->d_off; + /* Skip deleted files. */ + } while (de->d_ino == 0); + + if (de == NULL) { + *result = NULL; + } else { + *result = memcpy (entry, de, de->d_reclen); + } + ret = 0; + +all_done: + +#ifdef _POSIX_THREADS + pthread_mutex_unlock(dir->dd_lock); +#endif + return((de != NULL)? 0 : ret); +} -- cgit v1.2.3