Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <a646fa36-1067-a5b8-3bfb-293ebd1813da@evolvis.org>
Date: Sun, 19 Apr 2026 03:23:40 +0200 (CEST)
From: Thorsten Glaser <tg@...lvis.org>
To: musl@...ts.openwall.com
Subject: Re: [PATCH] scandir: fix qsort usage

On Sun, 12 Apr 2026, Rich Felker wrote:

>Maybe this was different at some point in distant history, or maybe
>the documentation was just wrong?

Things seem to differ vastly. At the point I forked off OpenBSD,
(I haven’t worked on it) its scandir(3) manpage is as follows:


SCANDIR(3)                 BSD Programmer's Manual                  SCANDIR(3)

NAME
     scandir, alphasort - scan a directory

SYNOPSIS
     #include <sys/types.h>
     #include <dirent.h>

     int
     scandir(const char *dirname, struct dirent ***namelist,
             int (*select)(struct dirent *),
             int (*compar)(const void *, const void *));

     int
     alphasort(const void *d1, const void *d2);

DESCRIPTION
     The scandir() function reads the directory dirname and builds an array of
     pointers to directory entries using malloc(3). It returns the number of
     entries in the array. A pointer to the array of directory entries is
     stored in the location referenced by namelist.

     The select parameter is a pointer to a user-supplied subroutine which is
     called by scandir() to select which entries are to be included in the ar-
     ray. The select routine is passed a pointer to a directory entry and
     should return a non-zero value if the directory entry is to be included
     in the array. If select is NULL, then all directory entries will be in-
     cluded.

     The compar parameter is a pointer to a user-supplied subroutine which is
     passed to qsort(3) to sort the completed array. If this pointer is NULL,
     the array is not sorted.

     The alphasort() function is a routine which can be used for the compar
     parameter to sort the array alphabetically.

     The memory allocated for the array can be deallocated with free(3), by
     freeing each pointer in the array and then the array itself.

DIAGNOSTICS
     Returns -1 if the directory cannot be opened for reading or if malloc(3)
     cannot allocate enough memory to hold all the data structures.

SEE ALSO
     directory(3), malloc(3), qsort(3), dir(5)

HISTORY
     The scandir() and alphasort() functions appeared in 4.2BSD.

MirOS BSD #10-current            June 4, 1993                                1


So this was definitely current in the BSDs for quite a while. OpenBSD
changed this in June 2013, with the following remark…

   The argument types for alphasort() and for the compar() argument to
   scandir() were originally void *, then changed to const void *, and
   then finally changed by IEEE Std 1003.1-2008 (“POSIX.1”) to their
   current form of const struct dirent **. Similarly, the select()
   argument to scandir() was originally struct dirent * until it was
   changed to its current form of const struct dirent *.

… to:

   int
   scandir(const char *dirname, struct dirent ***namelist,
           int (*select)(const struct dirent *),
           int (*compar)(const struct dirent **, const struct dirent **));

   int
   alphasort(const struct dirent **d1, const struct dirent **d2);

This is the current spelling, too.

bye,
//mirabilos
-- 
Solange man keine schmutzigen Tricks macht, und ich meine *wirklich*
schmutzige Tricks, wie bei einer doppelt verketteten Liste beide
Pointer XORen und in nur einem Word speichern, funktioniert Boehm ganz
hervorragend.		-- Andreas Bogk über boehm-gc in d.a.s.r

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.