Commit e2a5909ba3e for php.net
commit e2a5909ba3e2432ccf20fc8530a2f77e43149fd5
Author: David Carlier <devnexen@gmail.com>
Date: Thu Feb 19 12:47:54 2026 +0000
ext/pcntl: fix pcntl_setns() error handling.
Save errno into a local int before calling close(fd), as close() may
clobber errno on failure. Use int rather than errno_t because errno_t
is defined in C11 Annex K (bounds-checking interfaces) which is
optional and not widely implemented — many platforms (Linux/glibc,
musl, macOS, FreeBSD) do not provide it.
close GH-21256
diff --git a/NEWS b/NEWS
index 3c7e82dece6..8a0b3880255 100644
--- a/NEWS
+++ b/NEWS
@@ -41,6 +41,10 @@ PHP NEWS
- OpenSSL:
. Fix a bunch of leaks and error propagation. (ndossche)
+- PCNTL:
+ . Fixed pcntl_setns() internal errors handling regarding errnos.
+ (David Carlier)
+
- PDO_PGSQL:
. Fixed bug GH-21055 (connection attribute status typo for GSS negotiation).
(lsaos)
diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c
index 2034ca80b05..853215e39f9 100644
--- a/ext/pcntl/pcntl.c
+++ b/ext/pcntl/pcntl.c
@@ -1584,7 +1584,7 @@ PHP_FUNCTION(pcntl_setns)
pid = pid_is_null ? getpid() : pid;
fd = syscall(SYS_pidfd_open, pid, 0);
- if (errno) {
+ if (fd == -1) {
PCNTL_G(last_error) = errno;
switch (errno) {
case EINVAL:
@@ -1610,11 +1610,12 @@ PHP_FUNCTION(pcntl_setns)
RETURN_FALSE;
}
ret = setns(fd, (int)nstype);
+ int setns_errno = errno;
close(fd);
if (ret == -1) {
- PCNTL_G(last_error) = errno;
- switch (errno) {
+ PCNTL_G(last_error) = setns_errno;
+ switch (setns_errno) {
case ESRCH:
zend_argument_value_error(1, "process no longer available (" ZEND_LONG_FMT ")", pid);
RETURN_THROWS();
@@ -1624,11 +1625,11 @@ PHP_FUNCTION(pcntl_setns)
RETURN_THROWS();
case EPERM:
- php_error_docref(NULL, E_WARNING, "Error %d: No required capability for this process", errno);
+ php_error_docref(NULL, E_WARNING, "Error %d: No required capability for this process", setns_errno);
break;
default:
- php_error_docref(NULL, E_WARNING, "Error %d", errno);
+ php_error_docref(NULL, E_WARNING, "Error %d", setns_errno);
}
RETURN_FALSE;
} else {