View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001931 | 1003.1(2024)/Issue8 | System Interfaces | public | 2025-06-21 10:16 | 2025-06-24 09:23 |
Reporter | dag-erling | Assigned To | |||
Priority | normal | Severity | Editorial | Type | Clarification Requested |
Status | New | Resolution | Open | ||
Name | Dag-Erling Smørgrav | ||||
Organization | |||||
User Reference | |||||
Section | System Interfaces | ||||
Page Number | 614 | ||||
Line Number | 21757-21763, 21770-21772 | ||||
Interp Status | |||||
Final Accepted Text | |||||
Summary | 0001931: Behavior of scandir() when no entries are selected | ||||
Description | The description of `scandir()` does not specify whether `namelist` is expected to be null when no directory entries are selected (i.e. `scandir()` returns 0). The BSD implementation of `scandir()` allocates the pointer array before reading the directory and returns a non-null pointer which must be freed even if no entries were selected. This has been the case since the initial CSRG version in 1982. In macOS, which uses a direct descendant of this implementation, this is even documented in the manual page. The only difference between the CSRG, FreeBSD, and macOS implementations is the size of this initial allocation: the original implementation tried to guess how many pointers would be needed if all entries were selected, while FreeBSD, and later macOS, switched to an initial allocation size of 32 pointers. Solaris also appears to use a descendant of the CSRG implementation and still tries to preallocate the maximum number of pointers. Both glibc and musl, on the other hand, delay the allocation until the first entry is selected, so if `scandir()` returns 0, `namelist` is null. My main worry is that developers working primarily on Linux may treat the return value as trinary and return early if it is 0, failing to free `namelist`, not realizing that this will result in a memory leak when their code is run on e.g. FreeBSD. I'll also note that the code example in the specification frees `namelist` unconditionally as long as `scandir()` does not fail, but this does not really answer the question since a) the example calls `scandir()` without a selection function, so we can expect at least two entries for `.` and `..`, and b) `free(NULL)` is perfectly safe. | ||||
Desired Action | Either clarify whether `namelist` is expected to be null when `scandir()` returns 0, or explicitly leave it unspecified. | ||||
Tags | No tags attached. |
Date Modified | Username | Field | Change |
---|---|---|---|
2025-06-21 10:16 | dag-erling | New Issue | |
2025-06-21 10:18 | dag-erling | Note Added: 0007205 | |
2025-06-24 09:23 | geoffclare | Project | Issue 8 drafts => 1003.1(2024)/Issue8 |