From owner-svn-src-head@FreeBSD.ORG Tue Jan 5 20:20:32 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 377D11065676; Tue, 5 Jan 2010 20:20:32 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 1BE898FC17; Tue, 5 Jan 2010 20:20:32 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o05KKWhL002340; Tue, 5 Jan 2010 20:20:32 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o05KKVEp002337; Tue, 5 Jan 2010 20:20:31 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201001052020.o05KKVEp002337@svn.freebsd.org> From: Konstantin Belousov Date: Tue, 5 Jan 2010 20:20:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r201604 - head/lib/libc/gen X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Jan 2010 20:20:32 -0000 Author: kib Date: Tue Jan 5 20:20:31 2010 New Revision: 201604 URL: http://svn.freebsd.org/changeset/base/201604 Log: Do not rely on behaviour undefined by ANSI C, use thunks to adapt alphasort-like interface to the comparision function required by qsort() and qsort_r(). For opendir() thunk and alphasort(), comment on why we deviated from POSIX by using strcmp() instead of strcoll(). Requested and reviewed by: bde MFC after: 2 weeks Modified: head/lib/libc/gen/opendir.c head/lib/libc/gen/scandir.c Modified: head/lib/libc/gen/opendir.c ============================================================================== --- head/lib/libc/gen/opendir.c Tue Jan 5 20:18:41 2010 (r201603) +++ head/lib/libc/gen/opendir.c Tue Jan 5 20:20:31 2010 (r201604) @@ -93,6 +93,18 @@ __opendir2(const char *name, int flags) } /* + * POSIX 2008 and XSI 7 require alphasort() to call strcoll() for + * directory entries ordering. Use local copy that uses strcmp(). + */ +static int +opendir_alphasort(const void *p1, const void *p2) +{ + + return (strcmp((*(const struct dirent **)p1)->d_name, + (*(const struct dirent **)p2)->d_name)); +} + +/* * Common routine for opendir(3), __opendir2(3) and fdopendir(3). */ static DIR * @@ -240,8 +252,8 @@ __opendir_common(int fd, const char *nam /* * This sort must be stable. */ - mergesort(dpv, n, sizeof(*dpv), (int (*)(const - void *, const void *))alphasort); + mergesort(dpv, n, sizeof(*dpv), + opendir_alphasort); dpv[n] = NULL; xp = NULL; Modified: head/lib/libc/gen/scandir.c ============================================================================== --- head/lib/libc/gen/scandir.c Tue Jan 5 20:18:41 2010 (r201603) +++ head/lib/libc/gen/scandir.c Tue Jan 5 20:20:31 2010 (r201604) @@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$"); #include #include "un-namespace.h" +static int alphasort_thunk(void *thunk, const void *p1, const void *p2); + /* * The DIRSIZ macro is the minimum record length which will hold the directory * entry. This requires the amount of space in struct dirent without the @@ -109,8 +111,8 @@ scandir(const char *dirname, struct dire } closedir(dirp); if (nitems && dcomp != NULL) - qsort(names, nitems, sizeof(struct dirent *), - (int (*)(const void *, const void *))dcomp); + qsort_r(names, nitems, sizeof(struct dirent *), + &dcomp, alphasort_thunk); *namelist = names; return (nitems); @@ -124,6 +126,12 @@ fail: /* * Alphabetic order comparison routine for those who want it. + * + * XXXKIB POSIX 2008 requires the alphasort() to use strcoll(). Keep + * strcmp() for now, since environment locale settings could have no + * relevance for the byte sequence of the file name. Moreover, it + * might be even invalid sequence in current locale, and then + * behaviour of alphasort would be undefined. */ int alphasort(const struct dirent **d1, const struct dirent **d2) @@ -131,3 +139,12 @@ alphasort(const struct dirent **d1, cons return (strcmp((*d1)->d_name, (*d2)->d_name)); } + +static int +alphasort_thunk(void *thunk, const void *p1, const void *p2) +{ + int (*dc)(const struct dirent **, const struct dirent **); + + dc = *(int (**)(const struct dirent **, const struct dirent **))thunk; + return (dc((const struct dirent **)p1, (const struct dirent **)p2)); +}