xref: /netbsd-src/lib/libc/compat/gen/compat_readdir.c (revision 577cb3569f0afe3e06b4d33407247447b7356faf)
1*577cb356Smbalmer /*	$NetBSD: compat_readdir.c,v 1.3 2012/02/08 12:10:17 mbalmer Exp $	*/
25b84b398Schristos 
35b84b398Schristos #define __LIBC12_SOURCE__
45b84b398Schristos #include "namespace.h"
54b63973dSchristos #include <sys/param.h>
65b84b398Schristos #include <dirent.h>
74b63973dSchristos #include <errno.h>
84b63973dSchristos #include <string.h>
94b63973dSchristos #include <limits.h>
105b84b398Schristos #include <compat/include/dirent.h>
115b84b398Schristos 
125b84b398Schristos #ifdef __weak_alias
__weak_alias(readdir,_readdir)135b84b398Schristos __weak_alias(readdir,_readdir)
145b84b398Schristos __weak_alias(readdir_r,_readdir_r)
155b84b398Schristos #endif
165b84b398Schristos 
175b84b398Schristos #ifdef __warn_references
185b84b398Schristos __warn_references(readdir,
195b84b398Schristos     "warning: reference to compatibility readdir(); include <dirent.h> for correct reference")
205b84b398Schristos __warn_references(readdir_r,
215b84b398Schristos     "warning: reference to compatibility readdir_r(); include <dirent.h> for correct reference")
225b84b398Schristos #endif
235b84b398Schristos 
244b63973dSchristos static struct dirent12 *
254b63973dSchristos direnttodirent12(struct dirent12 *d12, const struct dirent *d)
264b63973dSchristos {
274b63973dSchristos 	if (d == NULL)
284b63973dSchristos 		return NULL;
295b84b398Schristos 
304b63973dSchristos 	if (d->d_fileno > UINT_MAX || d->d_namlen >= sizeof(d12->d_name)) {
314b63973dSchristos 		errno = ERANGE;
324b63973dSchristos 		return NULL;
334b63973dSchristos 	}
344b63973dSchristos 	d12->d_fileno = (uint32_t)d->d_fileno;
354b63973dSchristos 	d12->d_reclen = (uint16_t)d->d_reclen;
364b63973dSchristos 	d12->d_namlen = (uint8_t)MIN(d->d_namlen, sizeof(d->d_name) - 1);
374b63973dSchristos 	d12->d_type = (uint8_t)d->d_type;
38*577cb356Smbalmer 	memcpy(d12->d_name, d->d_name, (size_t)d12->d_namlen);
394b63973dSchristos 	d12->d_name[d12->d_namlen] = '\0';
404b63973dSchristos 	return d12;
414b63973dSchristos }
424b63973dSchristos 
434b63973dSchristos struct dirent12 *
readdir(DIR * dirp)444b63973dSchristos readdir(DIR *dirp)
454b63973dSchristos {
464b63973dSchristos 	static struct dirent12 d12;
474b63973dSchristos 	return direnttodirent12(&d12, __readdir30(dirp));
484b63973dSchristos }
494b63973dSchristos 
504b63973dSchristos int
readdir_r(DIR * dirp,struct dirent12 * entry,struct dirent12 ** result)514b63973dSchristos readdir_r(DIR *dirp, struct dirent12 *entry, struct dirent12 **result)
524b63973dSchristos {
534b63973dSchristos 	int error;
544b63973dSchristos 	struct dirent e, *ep;
554b63973dSchristos 
564b63973dSchristos 	if ((error = __readdir_r30(dirp, &e, &ep)) != 0)
574b63973dSchristos 		return error;
584b63973dSchristos 
594b63973dSchristos 	*result = entry;
604b63973dSchristos 	(void)direnttodirent12(entry, &e);
614b63973dSchristos 	return 0;
624b63973dSchristos }
63