standards/142255: scandir prototype in dirent.h isn't compliant with POSIX 2008

Kevin Barry ta0kira at users.berlios.de
Sun Jan 3 01:10:02 UTC 2010


>Number:         142255
>Category:       standards
>Synopsis:       scandir prototype in dirent.h isn't compliant with POSIX 2008
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-standards
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jan 03 01:10:01 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Kevin Barry
>Release:        8.0-RELEASE
>Organization:
>Environment:
FreeBSD kpbarry.student.cwru.edu 8.0-RELEASE FreeBSD 8.0-RELEASE #0: Sat Nov 21 15:02:08 UTC 2009     root at mason.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  amd64
>Description:
The POSIX standard declares 'scandir' as follows, copied directly:

int scandir(const char *dir, struct dirent ***namelist,
       int (*sel)(const struct dirent *),
       int (*compar)(const struct dirent **, const struct dirent **));

The problem in FreeBSD is the 'sel' argument, which is a pointer to a function taking a 'struct dirent *' without the 'const'. This is a problem when trying to write POSIX-portable code. In C I only receive a warning when trying to pass a function pointer of the correct type, however, in C++ this is an error. An argument cast isn't the solution because I still need my code to work in Linux; therefore, I've had to separate the call to 'scandir' in a C file, separate from the C++ code. Another solution is to C-cast a pointer to 'scandir' and dereference it, which I might consider. Thanks!
Kevin Barry
>How-To-Repeat:
#include <dirent.h>

static int sel(const struct dirent*)
{ return 1; }

int main()
{ scandir(0, 0, &sel, 0); }


Compile the above with g++.
>Fix:
Change the prototype of 'scandir' in dirent.h.

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-standards mailing list