Re: Allowing printf("%m") only where it actually works
Tom Lane <tgl@sss.pgh.pa.us>
I wrote:
> Consider the following approach:
> 1. Teach src/port/snprintf.c about %m. While I've not written a patch
> for this, it looks pretty trivial.
> 2. Teach configure to test for %m and if it's not there, use the
> replacement snprintf. (Note: we're already forcing snprintf replacement
> in cross-compiles, so the added run-time test isn't losing anything.)
> 3. Get rid of elog.c's hand-made substitution of %m strings, and instead
> just let it pass the correct errno value down. (We'd likely need to do
> some fooling in appendStringInfoVA and related functions to preserve
> call-time errno, but that's not complicated, nor expensive.)
> 4. (Optional) Get rid of strerror(errno) calls in favor of %m, even in
> frontend code.
So I started to hack on this, and soon noticed that actually, what elog.c
replaces %m with is *not* the result of strerror(), it's the result of
useful_strerror(). Which, primarily, does this:
/*
* Some strerror()s return an empty string for out-of-range errno. This
* is ANSI C spec compliant, but not exactly useful. Also, we may get
* back strings of question marks if libc cannot transcode the message to
* the codeset specified by LC_CTYPE. If we get nothing useful, first try
* get_errno_symbol(), and if that fails, print the numeric errno.
*/
I don't know offhand whether glibc's implementation delivers anything
useful for out-of-range errno, but I do know that we've seen the
transcoding problem with it, cf commit 8e68816cc which arose from
this discussion:
https://www.postgresql.org/message-id/flat/2782A2665E8342DF8695F396DBA80C88%40maumau
We could easily move useful_strerror() into snprintf.c, I think
(might need to move pgwin32_socket_strerror there too). But then
we'd lose its functionality when using glibc.
So now I'm about ready to propose that we just *always* use
snprintf.c, and forget all of the related configure probing.
This'd have some advantages, notably that we'd get the
useful_strerror() behavior in frontend as well as backend,
assuming we converted all our frontend code to use %m.
And we'd not exactly be the first project to decide that.
But it's kind of a big move from where we are today.
Thoughts?
regards, tom lane
Commits
-
In pg_log_generic(), be more paranoid about preserving errno.
- cf665ad4c89e 12.0 landed
- fb30c9c1c5c3 13.0 landed
-
Make src/common/exec.c's error logging less ugly.
- b6b297d20df9 12.0 landed
-
Select appropriate PG_PRINTF_ATTRIBUTE for recent NetBSD.
- aed9fa0bd897 12.0 landed
-
Fix detection of the result type of strerror_r().
- e5baf8c27e6c 9.4.20 landed
- 8b36dc588d10 9.5.15 landed
- 7871a36255e2 11.0 landed
- 2855421ec728 9.6.11 landed
- 0aa1e0ef167d 10.6 landed
- 08aad3c81eff 9.3.25 landed
-
Try another way to detect the result type of strerror_r().
- 751f532b9766 12.0 landed
-
Clean up *printf macros to avoid conflict with format archetypes.
- 8b91d258844a 12.0 landed
-
Fix link failures due to snprintf/strerror changes.
- a6b88d682cbe 12.0 landed
-
Implement %m in src/port/snprintf.c, and teach elog.c to rely on that.
- d6c55de1f99a 12.0 landed
-
Always use our own versions of *printf().
- 96bf88d52711 12.0 landed
-
Incorporate strerror_r() into src/port/snprintf.c, too.
- 758ce9b77948 12.0 landed
-
Convert elog.c's useful_strerror() into a globally-used strerror wrapper.
- 26e9d4d4ef16 12.0 landed
-
Revert "Distinguish printf-like functions that support %m from those that don't."
- 46b5e7c4b5be 12.0 landed
-
Produce compiler errors if errno is referenced inside elog/ereport calls.
- a2a8acd15217 12.0 landed
-
Distinguish printf-like functions that support %m from those that don't.
- 3a60c8ff892a 12.0 landed
-
Fix unportable usage of printf("%m").
- a13b47a59ffc 11.0 cited
-
Be more robust when strerror() doesn't give a useful result.
- 8e68816cc256 9.4.0 cited