<feed xmlns='http://www.w3.org/2005/Atom'>
<title>musl/src/dirent, branch master</title>
<subtitle>musl - an implementation of the standard library for Linux-based systems</subtitle>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/'/>
<entry>
<title>scandir: remove unused header</title>
<updated>2026-09-09T00:25:12+00:00</updated>
<author>
<name>Luca Kellermann</name>
<email>mailto.luca.kellermann@gmail.com</email>
</author>
<published>2026-04-15T21:00:50+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=4dad8af721e72b08c40df2c37558775a24987420'/>
<id>4dad8af721e72b08c40df2c37558775a24987420</id>
<content type='text'>
stddef.h is unused, commit da88b16a221c9d327e1bfa61dd6f4f08dacce57a
removed the use of offsetof().
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
stddef.h is unused, commit da88b16a221c9d327e1bfa61dd6f4f08dacce57a
removed the use of offsetof().
</pre>
</div>
</content>
</entry>
<entry>
<title>scandir: fix qsort usage</title>
<updated>2026-09-09T00:25:10+00:00</updated>
<author>
<name>Luca Kellermann</name>
<email>mailto.luca.kellermann@gmail.com</email>
</author>
<published>2026-04-15T18:08:44+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=0270c6f03b044de546e0808ef99efd8148a67435'/>
<id>0270c6f03b044de546e0808ef99efd8148a67435</id>
<content type='text'>
calling qsort() with a pointer to a function whose type is not
compatible with int(const void *, const void *) results in UB because
qsort() would call this function with an incompatible type.

avoid this by using qsort_r(). this is similar to how qsort() is
implemented on top of qsort_r().

the types of the pointers passed to wrapper_cmp() are
struct dirent *const * but the caller's comparison function expects
const struct dirent **. copy the pointer values into local variables
and pass their addresses to the caller's comparison function to get
the right type and avoid aliasing violations.

this is only necessary because the pointer to the comparison function
for scandir() was (incorrectly) specified as
int (*)(const struct dirent **, const struct dirent **) rather than
int (*)(struct dirent *const *, struct dirent *const *).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
calling qsort() with a pointer to a function whose type is not
compatible with int(const void *, const void *) results in UB because
qsort() would call this function with an incompatible type.

avoid this by using qsort_r(). this is similar to how qsort() is
implemented on top of qsort_r().

the types of the pointers passed to wrapper_cmp() are
struct dirent *const * but the caller's comparison function expects
const struct dirent **. copy the pointer values into local variables
and pass their addresses to the caller's comparison function to get
the right type and avoid aliasing violations.

this is only necessary because the pointer to the comparison function
for scandir() was (incorrectly) specified as
int (*)(const struct dirent **, const struct dirent **) rather than
int (*)(struct dirent *const *, struct dirent *const *).
</pre>
</div>
</content>
</entry>
<entry>
<title>scandir: report ENOMEM and EOVERFLOW</title>
<updated>2026-09-09T00:25:02+00:00</updated>
<author>
<name>Luca Kellermann</name>
<email>mailto.luca.kellermann@gmail.com</email>
</author>
<published>2025-07-20T23:29:52+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=0c34aa688ec1caf1011f1119892e2beb1960fc8b'/>
<id>0c34aa688ec1caf1011f1119892e2beb1960fc8b</id>
<content type='text'>
if the loop is exited because len * sizeof *names does not fit into
size_t, errno should be explicitly set to ENOMEM. previously, the
behavior differed depending on which value errno happened to have at
this point.

if cnt reached a value &gt; INT_MAX, scandir() returned an incorrect
value. EOVERFLOW should be reported instead.

it's unlikely that these errors can actually occur. it may not even
be possible to have directories with that many entries, and even then
malloc() or realloc() will probably fail long before len or cnt reach
those large values.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
if the loop is exited because len * sizeof *names does not fit into
size_t, errno should be explicitly set to ENOMEM. previously, the
behavior differed depending on which value errno happened to have at
this point.

if cnt reached a value &gt; INT_MAX, scandir() returned an incorrect
value. EOVERFLOW should be reported instead.

it's unlikely that these errors can actually occur. it may not even
be possible to have directories with that many entries, and even then
malloc() or realloc() will probably fail long before len or cnt reach
those large values.
</pre>
</div>
</content>
</entry>
<entry>
<title>scandir: disable cancellation around cancellation points</title>
<updated>2026-09-09T00:24:23+00:00</updated>
<author>
<name>Luca Kellermann</name>
<email>mailto.luca.kellermann@gmail.com</email>
</author>
<published>2026-04-15T14:54:57+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=187765a32a062715e6966a7ced3ec8af15cc1c0c'/>
<id>187765a32a062715e6966a7ced3ec8af15cc1c0c</id>
<content type='text'>
opendir() or closedir() might act upon a cancellation request. because
scandir() did not disable cancellation or install a cancellation
cleanup handler, this could lead to memory and file descriptor leaks.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
opendir() or closedir() might act upon a cancellation request. because
scandir() did not disable cancellation or install a cancellation
cleanup handler, this could lead to memory and file descriptor leaks.
</pre>
</div>
</content>
</entry>
<entry>
<title>scandir: don't examine errno after closedir()</title>
<updated>2026-09-09T00:23:53+00:00</updated>
<author>
<name>Luca Kellermann</name>
<email>mailto.luca.kellermann@gmail.com</email>
</author>
<published>2026-04-15T14:31:22+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=194f3481840990d961d0512fad30b7ed3fa9c110'/>
<id>194f3481840990d961d0512fad30b7ed3fa9c110</id>
<content type='text'>
when closedir() set errno, scandir() misinterpreted this as a failure.
this was wrong for two reasons:

* if closedir() succeeds, errno could still have been set, e.g. by
  __aio_close().

* even if closedir() "fails", it always closes the file descriptor and
  frees memory, so there is no reason to free all directory entries
  and return from scandir() with a failure.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
when closedir() set errno, scandir() misinterpreted this as a failure.
this was wrong for two reasons:

* if closedir() succeeds, errno could still have been set, e.g. by
  __aio_close().

* even if closedir() "fails", it always closes the file descriptor and
  frees memory, so there is no reason to free all directory entries
  and return from scandir() with a failure.
</pre>
</div>
</content>
</entry>
<entry>
<title>scandir: hide that errno is set to 0</title>
<updated>2026-09-09T00:23:27+00:00</updated>
<author>
<name>Luca Kellermann</name>
<email>mailto.luca.kellermann@gmail.com</email>
</author>
<published>2025-07-20T22:18:39+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=b5934c400ec53cc74a2a1156403ce1e7c3179b6c'/>
<id>b5934c400ec53cc74a2a1156403ce1e7c3179b6c</id>
<content type='text'>
POSIX.1-2024 requires that standard functions don't set errno to 0.
commit dae17a1aaf25d8333e729173d86659066607d87d ensured that cmp() and
the caller of scandir() cannot observe that errno is set to 0
internally. however, this was not yet the case for the sel() callback.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
POSIX.1-2024 requires that standard functions don't set errno to 0.
commit dae17a1aaf25d8333e729173d86659066607d87d ensured that cmp() and
the caller of scandir() cannot observe that errno is set to 0
internally. however, this was not yet the case for the sel() callback.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix mismatched type in posix_getdents definition</title>
<updated>2024-05-12T19:33:15+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2024-05-12T19:33:15+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=007997299248b8682dcbb73595c53dfe86071c83'/>
<id>007997299248b8682dcbb73595c53dfe86071c83</id>
<content type='text'>
commit 1b0d48517f816e98f19111df82f32bfc1608ecec wrongly copied the
getdents return type of int rather than matching the ssize_t used by
posix_getdents. this was overlooked in testing on 32-bit archs but
obviously broke 64-bit archs.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 1b0d48517f816e98f19111df82f32bfc1608ecec wrongly copied the
getdents return type of int rather than matching the ssize_t used by
posix_getdents. this was overlooked in testing on 32-bit archs but
obviously broke 64-bit archs.
</pre>
</div>
</content>
</entry>
<entry>
<title>implement posix_getdents adopted for next issue of POSIX</title>
<updated>2024-05-08T12:50:03+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2024-05-08T12:50:03+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=1b0d48517f816e98f19111df82f32bfc1608ecec'/>
<id>1b0d48517f816e98f19111df82f32bfc1608ecec</id>
<content type='text'>
this interface was added as the outcome of Austin Group tracker issue
697. no error is specified for unsupported flags, which is probably an
oversight. for now, EOPNOTSUPP is used so as not to overload EINVAL.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
this interface was added as the outcome of Austin Group tracker issue
697. no error is specified for unsupported flags, which is probably an
oversight. for now, EOPNOTSUPP is used so as not to overload EINVAL.
</pre>
</div>
</content>
</entry>
<entry>
<title>remove LFS64 symbol aliases; replace with dynamic linker remapping</title>
<updated>2022-10-19T18:01:31+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2022-09-26T21:14:18+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=246f1c811448f37a44b41cd8df8d0ef9736d95f4'/>
<id>246f1c811448f37a44b41cd8df8d0ef9736d95f4</id>
<content type='text'>
originally the namespace-infringing "large file support" interfaces
were included as part of glibc-ABI-compat, with the intent that they
not be used for linking, since our off_t is and always has been
unconditionally 64-bit and since we usually do not aim to support
nonstandard interfaces when there is an equivalent standard interface.

unfortunately, having the symbols present and available for linking
caused configure scripts to detect them and attempt to use them
without declarations, producing all the expected ill effects that
entails.

as a result, commit 2dd8d5e1b8ba1118ff1782e96545cb8a2318592c was made
to prevent this, using macros to redirect the LFS64 names to the
standard names, conditional on _GNU_SOURCE or _LARGEFILE64_SOURCE.
however, this has turned out to be a source of further problems,
especially since g++ defines _GNU_SOURCE by default. in particular,
the presence of these names as macros breaks a lot of valid code.

this commit removes all the LFS64 symbols and replaces them with a
mechanism in the dynamic linker symbol lookup failure path to retry
with the spurious "64" removed from the symbol name. in the future,
if/when the rest of glibc-ABI-compat is moved out of libc, this can be
removed.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
originally the namespace-infringing "large file support" interfaces
were included as part of glibc-ABI-compat, with the intent that they
not be used for linking, since our off_t is and always has been
unconditionally 64-bit and since we usually do not aim to support
nonstandard interfaces when there is an equivalent standard interface.

unfortunately, having the symbols present and available for linking
caused configure scripts to detect them and attempt to use them
without declarations, producing all the expected ill effects that
entails.

as a result, commit 2dd8d5e1b8ba1118ff1782e96545cb8a2318592c was made
to prevent this, using macros to redirect the LFS64 names to the
standard names, conditional on _GNU_SOURCE or _LARGEFILE64_SOURCE.
however, this has turned out to be a source of further problems,
especially since g++ defines _GNU_SOURCE by default. in particular,
the presence of these names as macros breaks a lot of valid code.

this commit removes all the LFS64 symbols and replaces them with a
mechanism in the dynamic linker symbol lookup failure path to retry
with the spurious "64" removed from the symbol name. in the future,
if/when the rest of glibc-ABI-compat is moved out of libc, this can be
removed.
</pre>
</div>
</content>
</entry>
<entry>
<title>fail fdopendir for O_PATH file descriptors</title>
<updated>2019-02-07T17:51:02+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2019-02-07T17:51:02+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=042b3ee452f542e0e16d847f90777e8c3a012375'/>
<id>042b3ee452f542e0e16d847f90777e8c3a012375</id>
<content type='text'>
fdopendir is specified to fail with EBADF if the file descriptor
passed is not open for reading. while O_PATH is an extension and
arguably exempt from this requirement, it's used, albeit incompletely,
to implement O_SEARCH, and fdopendir should fail when passed an
O_SEARCH file descriptor.

the new check is performed after fstat so that we don't have to
consider the possibility that the fd is invalid.

an alternate solution would be attempting to pre-fill the buffer using
getdents, which would fail with EBADF for us, but that seems more
complex and error-prone and involves either code duplication or
refactoring, so the simple fix with an additional inexpensive syscall
is what I've made for now.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
fdopendir is specified to fail with EBADF if the file descriptor
passed is not open for reading. while O_PATH is an extension and
arguably exempt from this requirement, it's used, albeit incompletely,
to implement O_SEARCH, and fdopendir should fail when passed an
O_SEARCH file descriptor.

the new check is performed after fstat so that we don't have to
consider the possibility that the fd is invalid.

an alternate solution would be attempting to pre-fill the buffer using
getdents, which would fail with EBADF for us, but that seems more
complex and error-prone and involves either code duplication or
refactoring, so the simple fix with an additional inexpensive syscall
is what I've made for now.
</pre>
</div>
</content>
</entry>
</feed>
