[klibc] [PATCH 1/3] klibc: Add scandir() and alphasort() support.

maximilian attems max at stro.at
Tue Aug 2 14:07:19 PDT 2011


On Fri, 29 Jul 2011, Mike Waychison wrote:

> Add support for scandir() and alphasort() as defined in POSIX.1-2008.
> 
> Signed-off-by: Mike Waychison <mikew at google.com>
> ---
>  usr/include/dirent.h |    7 +++++
>  usr/klibc/Kbuild     |    2 +
>  usr/klibc/scandir.c  |   76 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 84 insertions(+), 1 deletions(-)
>  create mode 100644 usr/klibc/scandir.c
> 
> diff --git a/usr/include/dirent.h b/usr/include/dirent.h
> index e324474..3b1ff59 100644
> --- a/usr/include/dirent.h
> +++ b/usr/include/dirent.h
> @@ -30,4 +30,11 @@ static __inline__ int dirfd(DIR * __d)
>  	return __d->__fd;
>  }
>  
> +__extern int scandir(const char *dirp, struct dirent ***namelist,
> +		     int (*filter)(const struct dirent *),
> +		     int (*compar)(const struct dirent **,
> +				   const struct dirent **));
> +
> +int alphasort(const struct dirent **a, const struct dirent **b);
> +
>  #endif				/* _DIRENT_H */

please no names in the header files, it breaks macros.

ah and alphasort needs __extern too.

> diff --git a/usr/klibc/Kbuild b/usr/klibc/Kbuild
> index af40367..40e61da 100644
> --- a/usr/klibc/Kbuild
> +++ b/usr/klibc/Kbuild
> @@ -42,7 +42,7 @@ klib-y := vsnprintf.o snprintf.o vsprintf.o sprintf.o \
>  	  seteuid.o setegid.o \
>  	  getenv.o setenv.o putenv.o __put_env.o unsetenv.o \
>  	  clearenv.o nullenv.o \
> -	  getopt.o getopt_long.o readdir.o remove.o \
> +	  getopt.o getopt_long.o readdir.o scandir.o remove.o \
>  	  syslog.o closelog.o pty.o getpt.o posix_openpt.o isatty.o reboot.o \
>  	  time.o utime.o llseek.o nice.o getpriority.o \
>  	  qsort.o bsearch.o \

please put alphasort in separate file.

> diff --git a/usr/klibc/scandir.c b/usr/klibc/scandir.c
> new file mode 100644
> index 0000000..1f58b15
> --- /dev/null
> +++ b/usr/klibc/scandir.c
> @@ -0,0 +1,76 @@
> +/*
> + * scandir.c: scandir/alphasort
> + */
> +
> +#include <stdlib.h>
> +#include <string.h>
> +#include <errno.h>
> +
> +#include <dirent.h>
> +
> +int scandir(const char *dirp, struct dirent ***namelist,
> +	    int (*filter)(const struct dirent *),
> +	    int (*compar)(const struct dirent **, const struct dirent **))
> +{
> +	struct dirent **nl = NULL, **next_nl;
> +	struct dirent *dirent;
> +	size_t count = 0;
> +	size_t allocated = 0;
> +	DIR *dir;
> +
> +	dir = opendir(dirp);
> +	if (!dir)
> +		return -1;
> +
> +	while (1) {
> +		dirent = readdir(dir);
> +		if (!dirent)
> +			break;
> +		if (!filter || filter(dirent)) {
> +			struct dirent *copy;
> +			copy = malloc(sizeof(*copy));
> +			if (!copy)
> +				goto cleanup_fail;
> +			memcpy(copy, dirent, sizeof(*copy));
> +
> +			/* Extend the array if needed */
> +			if (count == allocated) {
> +				if (allocated == 0)
> +					allocated = 15; /* ~1 page worth */
> +				else
> +					allocated *= 2;
> +				next_nl = realloc(nl, allocated);
> +				if (!next_nl) {
> +					free(copy);
> +					goto cleanup_fail;
> +				}
> +				nl = next_nl;
> +			}
> +
> +			nl[count++] = copy;
> +		}
> +	}
> +
> +	qsort(nl, count, sizeof(struct dirent *),
> +	      (int (*)(const void *, const void *))compar);
> +
> +	closedir(dir);
> +
> +	*namelist = nl;
> +	return count;
> +
> +cleanup_fail:
> +	while (count) {
> +		dirent = nl[--count];
> +		free(dirent);
> +	}
> +	free(nl);
> +	closedir(dir);
> +	errno = ENOMEM;
> +	return -1;
> +}
> +
> +int alphasort(const struct dirent **a, const struct dirent **b)
> +{
> +	return strcmp((*a)->d_name, (*b)->d_name);
> +}

other then that looks good, thanks to hpa for quick review.

-- 
maks

P.S. need to fix the sys/capability.h too.



More information about the klibc mailing list