Skip to content

Fix incorrect errno short names on FreeBSD/macOS in bwf::Errno#13240

Open
bryancall wants to merge 2 commits into
apache:masterfrom
bryancall:fix-errno-name-table
Open

Fix incorrect errno short names on FreeBSD/macOS in bwf::Errno#13240
bryancall wants to merge 2 commits into
apache:masterfrom
bryancall:fix-errno-name-table

Conversation

@bryancall
Copy link
Copy Markdown
Contributor

Problem

Reported in #13203. On FreeBSD (and macOS) Traffic Server logs connection
failures with a misleading errno name, e.g.:

CONNECT: attempt fail [CONNECTION_ERROR] to 72.167.35.147:443 for host='docs.trafficserver.apache.org' connection_result=ENOSTR [60] error=ENOSTR [60] retry_attempts=0 url='...'

ENOSTR ("Not a STREAM", an XSI STREAMS error) has nothing to do with the
actual failure, which made these logs confusing to diagnose. The numeric value
[60] is correct; only the symbolic name is wrong.

Root cause

swoc::bwf::Errno's short name used a single, hardcoded, Linux-numbered table
indexed directly by the raw errno value:

static const std::array<std::string_view, 134> ERRNO_SHORT_NAME = { "SUCCESS", "EPERM", ... };
auto errno_short_name = [](unsigned n) { return ERRNO_RANGE.contains(n) ? ERRNO_SHORT_NAME[n] : "Unknown"sv; };

errno numbering differs across platforms. Value 60 is ENOSTR on Linux but
ETIMEDOUT on FreeBSD/macOS (and ENOSTR is not defined at all on FreeBSD).
So a genuine connection timeout (ETIMEDOUT, errno 60) was printed as
ENOSTR. The numbering starts diverging at errno 11 and disagrees on roughly
70 of the values shared between Linux and the BSD-derived platforms, so this
was not a one-off.

Fix

Replace the single table with a per-platform table, each generated from that
platform's own <errno.h>, still looked up by O(1) direct index:

  • #if defined(__linux__) / #elif defined(__APPLE__) / #elif defined(__FreeBSD__).
  • Gaps in the numbering are empty entries that fall through to "Unknown".
  • An unsupported platform is a hard #error rather than silently wrong names.
  • The std::error_code formatter that shared the old table now routes through
    the same function.

The long form ({::l}) was already correct because it uses strerror(); this
only affects the symbolic short name. (Also drops a stray trailing space in the
old "E2BIG " entry.)

Testing

Compiled and verified on Linux, macOS, and FreeBSD 14.3. bwf::Errno(60) now
prints:

Platform before after
Linux ENOSTR ENOSTR (unchanged; 60 really is ENOSTR there)
FreeBSD / macOS ENOSTR ETIMEDOUT

Reproduced the original report on FreeBSD 14.3 against the 10.1.0 release: a
connection that timed out and logged connection_result=ENOSTR [60] now
reports ETIMEDOUT [60].

Fixes #13203

The errno short-name lookup indexed a single hardcoded Linux-numbered
table by the raw errno value, so on platforms with different numbering
it printed the wrong name. A connect timeout (ETIMEDOUT=60) was logged
as "ENOSTR" on FreeBSD/macOS, since 60 is ENOSTR only on Linux.

Replace the single table with a per-platform table generated from each
OS's own <errno.h>, keeping the O(1) direct index. Gaps fall through to
"Unknown" and an unsupported platform is a compile error.

Fixes: apache#13203
Copilot AI review requested due to automatic review settings June 4, 2026 20:31
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes swoc::bwf’s short-form errno formatting so that the symbolic name matches the platform’s actual <errno.h> numbering (not Linux’s numbering), addressing misleading log output on FreeBSD/macOS (e.g., ETIMEDOUT incorrectly printed as ENOSTR).

Changes:

  • Replaces the single Linux-numbered errno name table with per-platform tables for Linux, macOS, and FreeBSD.
  • Adds an errno_short_name(int) helper used by both bwf::Errno and the std::error_code formatter.
  • Preserves long-form errno formatting via strerror() while correcting short-form symbolic names.

Comment thread lib/swoc/src/bw_format.cc Outdated
Comment thread lib/swoc/src/bw_format.cc Outdated
The FreeBSD table was missing EPERM (errno 1), so it formatted as
"Unknown". Linux and FreeBSD also picked the ENOTSUP alias over the
more common EOPNOTSUPP for that value, which changed existing log
output. Prefer the canonical name (EAGAIN/EDEADLK/EOPNOTSUPP) and fill
in EPERM.

Add a test_bw_format case asserting bwf::Errno prints the platform's
own symbolic name for EPERM, ETIMEDOUT, and ECONNREFUSED, guarding
against the mislabel this PR fixes.
Copy link
Copy Markdown
Contributor

@masaori335 masaori335 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having the list per supported platform makes sense to keep it O(1) at lookup.

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

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Incorrect error code/string (ENOSTR)

3 participants