Skip to content

ext/posix: remove musl pathconf workarounds#22717

Open
orlitzky wants to merge 1 commit into
php:PHP-8.5from
orlitzky:musl-pathconf
Open

ext/posix: remove musl pathconf workarounds#22717
orlitzky wants to merge 1 commit into
php:PHP-8.5from
orlitzky:musl-pathconf

Conversation

@orlitzky

Copy link
Copy Markdown
Contributor

We have a test in build/php.m4 for the C library (glibc, musl, etc.) that is used to skip the pathconf() and fpathconf() checks in ext/posix/config.m4. They are skipped on musl because the musl implementations do not validate their first arguments, and in the past that lead to two test failures: one for posix_pathconf(), and one for posix_fpathconf().

In php >= 8.5, the posix_fpathconf() wrapper now validates the file descriptor itself, so there is no longer any need to exclude musl in that case.

The other failure in posix_pathconf() looks for an error when using a non-existent path. POSIX however allows the implementation to ignore the path when it will not affect the result, meaning that musl is fully compliant here. And as we obtain the correct answer in lieu of an error, I think it is fine to accept the musl implementation here as well.

This commit removes the build-time musl exception, and updates the one failing test to expect either a failure (glibc), or an integer response (musl) when given an invalid path.

The relevant POSIX page is https://pubs.opengroup.org/onlinepubs/9799919799/functions/pathconf.html, but you have to read the RATIONALE section for the juicy bit:

Also note that most of the errors are optional. If one of the variables always has the same value on an implementation, the implementation need not look at path or fildes to return that value and is, therefore, not required to detect any of the errors except the meaning of [EINVAL] that indicates that the value of name is not valid for that variable, and the [EOVERFLOW] error that indicates the value to be returned is larger than {LONG_MAX}.

Targeting PHP-8.5 where posix_fpathconf() already works, but the same approach can be used in posix_fpathconf.phpt for PHP-8.4.

We have a test in build/php.m4 for the C library (glibc, musl, etc.)
that is used to skip the pathconf() and fpathconf() checks in
ext/posix/config.m4. They are skipped on musl because the musl
implementations do not validate their first arguments, and in the past
that lead to two test failures: one for posix_pathconf(), and one for
posix_fpathconf().

In php >= 8.5, the posix_fpathconf() wrapper now validates the file
descriptor itself, so there is no longer any need to exclude musl in
that case.

The other failure in posix_pathconf() looks for an error when using a
non-existent path. POSIX however allows the implementation to ignore
the path when it will not affect the result, meaning that musl is
fully compliant here. And as we obtain the correct answer in lieu of
an error, I think it is fine to accept the musl implementation here as
well.

This commit removes the build-time musl exception, and updates the one
failing test to expect either a failure (glibc), or an integer
response (musl) when given an invalid path.
@orlitzky orlitzky changed the base branch from master to PHP-8.5 July 13, 2026 19:42
@orlitzky

Copy link
Copy Markdown
Contributor Author

cc @petk

@petk

petk commented Jul 13, 2026

Copy link
Copy Markdown
Member

That sounds good to me. In PHP 8.5 these functions on Alpine (musl library) then work the same way as on other Linux distros (glibc-based)? Then the check can be removed for sure, yes. Otherwise, if under the musl library there is still different return value, I'm not sure...

@orlitzky

Copy link
Copy Markdown
Contributor Author

They don't act exactly the same, but both musl and glibc adhere to POSIX, their own documentation, and PHP's documentation.

When asking for a limit relative to some path, you run pathconf(path, LIMIT_NAME) if you have the path, or fpathconf(fd, LIMIT_NAME) if you have a file descriptor to that path. POSIX specifically says that if LIMIT_NAME does not depend on the path, the path or file descriptor can be junk and you'll still get the answer back. Musl does that, but glibc apparently does not. Either way is legal, and I don't think any user will be disappointed to get the correct answer instead of an error.

Prior to 8.5, the PHP docs for the two posix_pathconf() and posix_fpathconf() wrappers don't mention it, but there are tests for the error cases. In PHP-8.5, posix_fpathconf() was updated to validate the file descriptor itself. This was a mistake IMO, but the docs were updated, and now the musl/glibc behaviors are the same wrt invalid descriptors. (PHP fails before musl can return the correct answer.)

Invalid paths can still be passed to posix_pathconf(), and the invalidity is ignored by musl, but not glibc. Nothing says that an error should be raised, however, and I don't think the test is there to enforce behavior (I think it's testing that libc errors get converted to PHP's false). On musl you get back the correct answer instead of an error -- who's going to argue with that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants