diff options
| author | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-12-28 12:13:40 +0100 |
|---|---|---|
| committer | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-12-28 12:13:40 +0100 |
| commit | b0afb8fe0ff1d87165af9df61501197a06240dda (patch) | |
| tree | 274ac6a96c53ef4c19ab4974ce24a06a233128c5 /gl/error.c | |
| parent | 68fc05381ee5fa0aee1413118fbb3d81ca888b09 (diff) | |
| download | monitoring-plugins-b0afb8fe0ff1d87165af9df61501197a06240dda.tar.gz | |
Sync with Gnulib stable-202507 code (a8ac9f9ce5)
Diffstat (limited to 'gl/error.c')
| -rw-r--r-- | gl/error.c | 177 |
1 files changed, 71 insertions, 106 deletions
| @@ -1,25 +1,32 @@ | |||
| 1 | /* Error handler for noninteractive utilities | 1 | /* Error handler for noninteractive utilities |
| 2 | Copyright (C) 1990-1998, 2000-2007, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1990-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | The GNU C Library is free software; you can redistribute it and/or |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | modify it under the terms of the GNU Lesser General Public |
| 7 | published by the Free Software Foundation; either version 2.1 of the | 7 | License as published by the Free Software Foundation; either |
| 8 | License, or (at your option) any later version. | 8 | version 2.1 of the License, or (at your option) any later version. |
| 9 | 9 | ||
| 10 | This file is distributed in the hope that it will be useful, | 10 | The GNU C Library is distributed in the hope that it will be useful, |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | GNU Lesser General Public License for more details. | 13 | Lesser General Public License for more details. |
| 14 | 14 | ||
| 15 | You should have received a copy of the GNU Lesser General Public License | 15 | You should have received a copy of the GNU Lesser General Public |
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | 16 | License along with the GNU C Library; if not, see |
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 17 | 18 | ||
| 18 | /* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ | 19 | /* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ |
| 19 | 20 | ||
| 20 | #if !_LIBC | 21 | #if !_LIBC |
| 21 | # include <config.h> | 22 | # include <config.h> |
| 22 | # define _GL_NO_INLINE_ERROR | 23 | # define _GL_NO_INLINE_ERROR |
| 24 | # define __error_internal(status, err, fmt, args, flags) \ | ||
| 25 | verror (status, err, fmt, args) | ||
| 26 | # define __error_at_line_internal(status, err, file, line, fmt, args, flags) \ | ||
| 27 | verror_at_line (status, err, file, line, fmt, args) | ||
| 28 | # define error_tail(status, err, fmt, args, flags) \ | ||
| 29 | error_tail (status, err, fmt, args) | ||
| 23 | #endif | 30 | #endif |
| 24 | 31 | ||
| 25 | #include <error.h> | 32 | #include <error.h> |
| @@ -31,7 +38,7 @@ | |||
| 31 | 38 | ||
| 32 | #if !_LIBC && ENABLE_NLS | 39 | #if !_LIBC && ENABLE_NLS |
| 33 | # include "gettext.h" | 40 | # include "gettext.h" |
| 34 | # define _(msgid) gettext (msgid) | 41 | # define _(msgid) dgettext ("gnulib", msgid) |
| 35 | #endif | 42 | #endif |
| 36 | 43 | ||
| 37 | #ifdef _LIBC | 44 | #ifdef _LIBC |
| @@ -85,7 +92,7 @@ extern void __error_at_line (int status, int errnum, const char *file_name, | |||
| 85 | # undef putc | 92 | # undef putc |
| 86 | # define putc(c, fp) _IO_putc (c, fp) | 93 | # define putc(c, fp) _IO_putc (c, fp) |
| 87 | 94 | ||
| 88 | # include <bits/libc-lock.h> | 95 | # include <libc-lock.h> |
| 89 | 96 | ||
| 90 | #else /* not _LIBC */ | 97 | #else /* not _LIBC */ |
| 91 | 98 | ||
| @@ -123,6 +130,13 @@ int strerror_r (int errnum, char *buf, size_t buflen); | |||
| 123 | # if GNULIB_STRERROR_R_POSIX || HAVE_STRERROR_R || defined strerror_r | 130 | # if GNULIB_STRERROR_R_POSIX || HAVE_STRERROR_R || defined strerror_r |
| 124 | # define __strerror_r strerror_r | 131 | # define __strerror_r strerror_r |
| 125 | # endif /* GNULIB_STRERROR_R_POSIX || HAVE_STRERROR_R || defined strerror_r */ | 132 | # endif /* GNULIB_STRERROR_R_POSIX || HAVE_STRERROR_R || defined strerror_r */ |
| 133 | |||
| 134 | # if GNULIB_defined_verror | ||
| 135 | # undef verror | ||
| 136 | # endif | ||
| 137 | # if GNULIB_defined_verror_at_line | ||
| 138 | # undef verror_at_line | ||
| 139 | # endif | ||
| 126 | #endif /* not _LIBC */ | 140 | #endif /* not _LIBC */ |
| 127 | 141 | ||
| 128 | #if !_LIBC | 142 | #if !_LIBC |
| @@ -151,8 +165,8 @@ flush_stdout (void) | |||
| 151 | #if !_LIBC | 165 | #if !_LIBC |
| 152 | int stdout_fd; | 166 | int stdout_fd; |
| 153 | 167 | ||
| 154 | # if GNULIB_FREOPEN_SAFER | 168 | # if GNULIB_FREOPEN_SAFER || GNULIB_XSTDOPEN |
| 155 | /* Use of gnulib's freopen-safer module normally ensures that | 169 | /* Gnulib's freopen-safer and/or xstdopen modules normally ensure that |
| 156 | fileno (stdout) == 1 | 170 | fileno (stdout) == 1 |
| 157 | whenever stdout is open. */ | 171 | whenever stdout is open. */ |
| 158 | stdout_fd = STDOUT_FILENO; | 172 | stdout_fd = STDOUT_FILENO; |
| @@ -183,7 +197,7 @@ print_errno_message (int errnum) | |||
| 183 | if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0) | 197 | if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0) |
| 184 | s = errbuf; | 198 | s = errbuf; |
| 185 | else | 199 | else |
| 186 | s = 0; | 200 | s = NULL; |
| 187 | # endif | 201 | # endif |
| 188 | #else | 202 | #else |
| 189 | s = strerror (errnum); | 203 | s = strerror (errnum); |
| @@ -202,75 +216,18 @@ print_errno_message (int errnum) | |||
| 202 | } | 216 | } |
| 203 | 217 | ||
| 204 | static void _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0) _GL_ARG_NONNULL ((3)) | 218 | static void _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0) _GL_ARG_NONNULL ((3)) |
| 205 | error_tail (int status, int errnum, const char *message, va_list args) | 219 | error_tail (int status, int errnum, const char *message, va_list args, |
| 220 | unsigned int mode_flags) | ||
| 206 | { | 221 | { |
| 207 | #if _LIBC | 222 | #if _LIBC |
| 208 | if (_IO_fwide (stderr, 0) > 0) | 223 | int ret = __vfxprintf (stderr, message, args, mode_flags); |
| 209 | { | 224 | if (ret < 0 && errno == ENOMEM && _IO_fwide (stderr, 0) > 0) |
| 210 | size_t len = strlen (message) + 1; | 225 | /* Leave a trace in case the heap allocation of the message string |
| 211 | wchar_t *wmessage = NULL; | 226 | failed. */ |
| 212 | mbstate_t st; | 227 | fputws_unlocked (L"out of memory\n", stderr); |
| 213 | size_t res; | 228 | #else |
| 214 | const char *tmp; | 229 | vfprintf (stderr, message, args); |
| 215 | bool use_malloc = false; | ||
| 216 | |||
| 217 | while (1) | ||
| 218 | { | ||
| 219 | if (__libc_use_alloca (len * sizeof (wchar_t))) | ||
| 220 | wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); | ||
| 221 | else | ||
| 222 | { | ||
| 223 | if (!use_malloc) | ||
| 224 | wmessage = NULL; | ||
| 225 | |||
| 226 | wchar_t *p = (wchar_t *) realloc (wmessage, | ||
| 227 | len * sizeof (wchar_t)); | ||
| 228 | if (p == NULL) | ||
| 229 | { | ||
| 230 | free (wmessage); | ||
| 231 | fputws_unlocked (L"out of memory\n", stderr); | ||
| 232 | return; | ||
| 233 | } | ||
| 234 | wmessage = p; | ||
| 235 | use_malloc = true; | ||
| 236 | } | ||
| 237 | |||
| 238 | memset (&st, '\0', sizeof (st)); | ||
| 239 | tmp = message; | ||
| 240 | |||
| 241 | res = mbsrtowcs (wmessage, &tmp, len, &st); | ||
| 242 | if (res != len) | ||
| 243 | break; | ||
| 244 | |||
| 245 | if (__builtin_expect (len >= SIZE_MAX / sizeof (wchar_t) / 2, 0)) | ||
| 246 | { | ||
| 247 | /* This really should not happen if everything is fine. */ | ||
| 248 | res = (size_t) -1; | ||
| 249 | break; | ||
| 250 | } | ||
| 251 | |||
| 252 | len *= 2; | ||
| 253 | } | ||
| 254 | |||
| 255 | if (res == (size_t) -1) | ||
| 256 | { | ||
| 257 | /* The string cannot be converted. */ | ||
| 258 | if (use_malloc) | ||
| 259 | { | ||
| 260 | free (wmessage); | ||
| 261 | use_malloc = false; | ||
| 262 | } | ||
| 263 | wmessage = (wchar_t *) L"???"; | ||
| 264 | } | ||
| 265 | |||
| 266 | __vfwprintf (stderr, wmessage, args); | ||
| 267 | |||
| 268 | if (use_malloc) | ||
| 269 | free (wmessage); | ||
| 270 | } | ||
| 271 | else | ||
| 272 | #endif | 230 | #endif |
| 273 | vfprintf (stderr, message, args); | ||
| 274 | 231 | ||
| 275 | ++error_message_count; | 232 | ++error_message_count; |
| 276 | if (errnum) | 233 | if (errnum) |
| @@ -291,16 +248,14 @@ error_tail (int status, int errnum, const char *message, va_list args) | |||
| 291 | If ERRNUM is nonzero, print its corresponding system error message. | 248 | If ERRNUM is nonzero, print its corresponding system error message. |
| 292 | Exit with status STATUS if it is nonzero. */ | 249 | Exit with status STATUS if it is nonzero. */ |
| 293 | void | 250 | void |
| 294 | error (int status, int errnum, const char *message, ...) | 251 | __error_internal (int status, int errnum, const char *message, |
| 252 | va_list args, unsigned int mode_flags) | ||
| 295 | { | 253 | { |
| 296 | va_list args; | 254 | #if defined _LIBC |
| 297 | |||
| 298 | #if defined _LIBC && defined __libc_ptf_call | ||
| 299 | /* We do not want this call to be cut short by a thread | 255 | /* We do not want this call to be cut short by a thread |
| 300 | cancellation. Therefore disable cancellation for now. */ | 256 | cancellation. Therefore disable cancellation for now. */ |
| 301 | int state = PTHREAD_CANCEL_ENABLE; | 257 | int state = PTHREAD_CANCEL_ENABLE; |
| 302 | __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), | 258 | __pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state); |
| 303 | 0); | ||
| 304 | #endif | 259 | #endif |
| 305 | 260 | ||
| 306 | flush_stdout (); | 261 | flush_stdout (); |
| @@ -318,28 +273,32 @@ error (int status, int errnum, const char *message, ...) | |||
| 318 | #endif | 273 | #endif |
| 319 | } | 274 | } |
| 320 | 275 | ||
| 321 | va_start (args, message); | 276 | error_tail (status, errnum, message, args, mode_flags); |
| 322 | error_tail (status, errnum, message, args); | ||
| 323 | va_end (args); | ||
| 324 | 277 | ||
| 325 | #ifdef _LIBC | 278 | #ifdef _LIBC |
| 326 | _IO_funlockfile (stderr); | 279 | _IO_funlockfile (stderr); |
| 327 | # ifdef __libc_ptf_call | 280 | __pthread_setcancelstate (state, NULL); |
| 328 | __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); | ||
| 329 | # endif | ||
| 330 | #endif | 281 | #endif |
| 331 | } | 282 | } |
| 283 | |||
| 284 | void | ||
| 285 | error (int status, int errnum, const char *message, ...) | ||
| 286 | { | ||
| 287 | va_list ap; | ||
| 288 | va_start (ap, message); | ||
| 289 | __error_internal (status, errnum, message, ap, 0); | ||
| 290 | va_end (ap); | ||
| 291 | } | ||
| 332 | 292 | ||
| 333 | /* Sometimes we want to have at most one error per line. This | 293 | /* Sometimes we want to have at most one error per line. This |
| 334 | variable controls whether this mode is selected or not. */ | 294 | variable controls whether this mode is selected or not. */ |
| 335 | int error_one_per_line; | 295 | int error_one_per_line; |
| 336 | 296 | ||
| 337 | void | 297 | void |
| 338 | error_at_line (int status, int errnum, const char *file_name, | 298 | __error_at_line_internal (int status, int errnum, const char *file_name, |
| 339 | unsigned int line_number, const char *message, ...) | 299 | unsigned int line_number, const char *message, |
| 300 | va_list args, unsigned int mode_flags) | ||
| 340 | { | 301 | { |
| 341 | va_list args; | ||
| 342 | |||
| 343 | if (error_one_per_line) | 302 | if (error_one_per_line) |
| 344 | { | 303 | { |
| 345 | static const char *old_file_name; | 304 | static const char *old_file_name; |
| @@ -358,12 +317,11 @@ error_at_line (int status, int errnum, const char *file_name, | |||
| 358 | old_line_number = line_number; | 317 | old_line_number = line_number; |
| 359 | } | 318 | } |
| 360 | 319 | ||
| 361 | #if defined _LIBC && defined __libc_ptf_call | 320 | #if defined _LIBC |
| 362 | /* We do not want this call to be cut short by a thread | 321 | /* We do not want this call to be cut short by a thread |
| 363 | cancellation. Therefore disable cancellation for now. */ | 322 | cancellation. Therefore disable cancellation for now. */ |
| 364 | int state = PTHREAD_CANCEL_ENABLE; | 323 | int state = PTHREAD_CANCEL_ENABLE; |
| 365 | __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), | 324 | __pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state); |
| 366 | 0); | ||
| 367 | #endif | 325 | #endif |
| 368 | 326 | ||
| 369 | flush_stdout (); | 327 | flush_stdout (); |
| @@ -389,18 +347,25 @@ error_at_line (int status, int errnum, const char *file_name, | |||
| 389 | file_name, line_number); | 347 | file_name, line_number); |
| 390 | #endif | 348 | #endif |
| 391 | 349 | ||
| 392 | va_start (args, message); | 350 | error_tail (status, errnum, message, args, mode_flags); |
| 393 | error_tail (status, errnum, message, args); | ||
| 394 | va_end (args); | ||
| 395 | 351 | ||
| 396 | #ifdef _LIBC | 352 | #ifdef _LIBC |
| 397 | _IO_funlockfile (stderr); | 353 | _IO_funlockfile (stderr); |
| 398 | # ifdef __libc_ptf_call | 354 | __pthread_setcancelstate (state, NULL); |
| 399 | __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); | ||
| 400 | # endif | ||
| 401 | #endif | 355 | #endif |
| 402 | } | 356 | } |
| 403 | 357 | ||
| 358 | void | ||
| 359 | error_at_line (int status, int errnum, const char *file_name, | ||
| 360 | unsigned int line_number, const char *message, ...) | ||
| 361 | { | ||
| 362 | va_list ap; | ||
| 363 | va_start (ap, message); | ||
| 364 | __error_at_line_internal (status, errnum, file_name, line_number, | ||
| 365 | message, ap, 0); | ||
| 366 | va_end (ap); | ||
| 367 | } | ||
| 368 | |||
| 404 | #ifdef _LIBC | 369 | #ifdef _LIBC |
| 405 | /* Make the weak alias. */ | 370 | /* Make the weak alias. */ |
| 406 | # undef error | 371 | # undef error |
