Fix errno handling in popen_check() to avoid false error reports

From: ma lz <ma100(at)hotmail(dot)com>
To: "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>
Subject: Fix errno handling in popen_check() to avoid false error reports
Date: 2026-03-04 08:14:24
Message-ID: TYRPR01MB1587010C4A65D47D0E6E60122F27CA@TYRPR01MB15870.jpnprd01.prod.outlook.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi Hackers,
I noticed a potential issue in popen_check() (src/common/wait_error.c) regarding errno handling when popen() succeeds but leaves a non-zero errno behind.
Problem
In certain environments (e.g., CentOS 7 host with Docker container running Euler 24.03, older kernel), popen() internally first tries clone3, which fails with ENOSYS (38), then falls back to traditional clone and succeeds. However, the errno value from the failed clone3 attempt (38) is not cleared, so after a successful popen(), errno remains 38.
Current code in popen_check():
c

errno = 0;
cmdfd = popen(command, mode);
if (cmdfd == NULL)
pg_log_error("could not execute command \"%s\": %m", command);
return cmdfd;

If a caller (incorrectly) checks errno even when popen() succeeds, they might see errno == ENOSYS and mistakenly believe an error occurred, even though the command executed successfully.
Proposed Fix
Move errno = 0 to the success path, so errno is only cleared when popen() actually succeeds:
c

cmdfd = popen(command, mode);
if (cmdfd == NULL) {
pg_log_error("could not execute command \"%s\": %m", command);
} else {
/* Success: clear any stale errno from internal fallback attempts */
errno = 0;
}
return cmdfd;

This ensures that after a successful popen(), errno is zero, preventing any confusion in upper layers that might (for historical reasons) inspect errno even on success.
Testing
I tested this change in the environment where the issue was observed:

*
Host: CentOS 7
*
Container: Euler 24.03 (glibc compiled with __ASSUME_CLONE3)
*
Before the fix: errno remained 38 after successful popen()
*
After the fix: errno is properly reset to 0

All regression tests pass.

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Michael Paquier 2026-03-04 08:23:29 Re: BUG: Former primary node might stuck when started as a standby
Previous Message Tatsuo Ishii 2026-03-04 08:12:03 Re: Row pattern recognition