diff options
| author | Eric Andersen <andersen@codepoet.org> | 2002-08-26 18:46:06 +0000 | 
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 2002-08-26 18:46:06 +0000 | 
| commit | 4cd5ca906c65b15fc966b9d02d3f0cc1ae8817ff (patch) | |
| tree | 96e579955e4868b5dd710324d1e44172da97de8d | |
| parent | 22fa952fdb5e9d2c5b1ee0d6c3fb75974ca15666 (diff) | |
Implement missing readdir64_r.c
 -Erik
| -rw-r--r-- | libc/misc/dirent/Makefile | 3 | ||||
| -rw-r--r-- | libc/misc/dirent/readdir64_r.c | 79 | 
2 files changed, 81 insertions, 1 deletions
diff --git a/libc/misc/dirent/Makefile b/libc/misc/dirent/Makefile index d50cdb520..c3dc95a8f 100644 --- a/libc/misc/dirent/Makefile +++ b/libc/misc/dirent/Makefile @@ -25,7 +25,8 @@ TOPDIR=../../../  include $(TOPDIR)Rules.mak  CSRC=alphasort.c closedir.c dirfd.c opendir.c readdir.c rewinddir.c scandir.c \ -     	seekdir.c telldir.c readdir64.c alphasort64.c scandir64.c readdir_r.c +     	seekdir.c telldir.c readdir64.c alphasort64.c scandir64.c readdir_r.c \ +	readdir64_r.c  COBJS=$(patsubst %.c,%.o, $(CSRC))  OBJS=$(COBJS) diff --git a/libc/misc/dirent/readdir64_r.c b/libc/misc/dirent/readdir64_r.c new file mode 100644 index 000000000..6735db8d8 --- /dev/null +++ b/libc/misc/dirent/readdir64_r.c @@ -0,0 +1,79 @@ +#include <features.h> +#ifdef __UCLIBC_HAVE_LFS__ +#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS != 64  +#undef _FILE_OFFSET_BITS +#define	_FILE_OFFSET_BITS   64 +#endif +#ifndef __USE_LARGEFILE64 +# define __USE_LARGEFILE64	1 +#endif +/* We absolutely do _NOT_ want interfaces silently + * renamed under us or very bad things will happen... */ +#ifdef __USE_FILE_OFFSET64 +# undef __USE_FILE_OFFSET64 +#endif +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <dirent.h> +#include "dirstream.h" + +extern int getdents64 __P ((unsigned int fd, struct dirent64 *dirp, unsigned int count)); + + +int readdir64_r(DIR *dir, struct dirent64 *entry, struct dirent64 **result) +{ +	int ret; +	ssize_t bytes; +	struct dirent64 *de; + +	if (!dir) { +	    __set_errno(EBADF); +	    return(EBADF); +	} +	de = NULL; + +#ifdef __UCLIBC_HAS_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 = getdents64(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 dirent64 *) (((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 __UCLIBC_HAS_THREADS__ +	pthread_mutex_unlock(&(dir->dd_lock)); +#endif +        return((de != NULL)? 0 : ret); +} +#endif /* __UCLIBC_HAVE_LFS__ */ +  | 
