summaryrefslogtreecommitdiffstats
path: root/gl/error.c
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-12-28 12:13:40 +0100
committerLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-12-28 12:13:40 +0100
commitb0afb8fe0ff1d87165af9df61501197a06240dda (patch)
tree274ac6a96c53ef4c19ab4974ce24a06a233128c5 /gl/error.c
parent68fc05381ee5fa0aee1413118fbb3d81ca888b09 (diff)
downloadmonitoring-plugins-b0afb8fe0ff1d87165af9df61501197a06240dda.tar.gz
Sync with Gnulib stable-202507 code (a8ac9f9ce5)
Diffstat (limited to 'gl/error.c')
-rw-r--r--gl/error.c177
1 files changed, 71 insertions, 106 deletions
diff --git a/gl/error.c b/gl/error.c
index c53dfeb6..9231c79c 100644
--- a/gl/error.c
+++ b/gl/error.c
@@ -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
204static void _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0) _GL_ARG_NONNULL ((3)) 218static void _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0) _GL_ARG_NONNULL ((3))
205error_tail (int status, int errnum, const char *message, va_list args) 219error_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. */
293void 250void
294error (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
284void
285error (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. */
335int error_one_per_line; 295int error_one_per_line;
336 296
337void 297void
338error_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
358void
359error_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