1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <stdarg.h>
21: #include <err.h>
22: #include <stdlib.h>
23: #include <errno.h>
24: #include <string.h>
25: #include <stdio.h>
26:
27: #ifdef USE_IN_LIBIO
28: # include <wchar.h>
29: # define flockfile(s) _IO_flockfile (s)
30: # define funlockfile(s) _IO_funlockfile (s)
31: #endif
32:
33: extern char *__progname;
34:
35: #define VA(call) \
36: { \
37: va_list ap; \
38: va_start (ap, format); \
39: call; \
40: va_end (ap); \
41: }
42:
43: #ifdef USE_IN_LIBIO
44: static void
45: convert_and_print (const char *format, __gnuc_va_list ap)
46: {
47: # define ALLOCA_LIMIT 2000
48: size_t len;
49: wchar_t *wformat = NULL;
50: mbstate_t st;
51: size_t res;
52: const char *tmp;
53:
54: if (format == NULL)
55: return;
56:
57: len = strlen (format) + 1;
58:
59: do
60: {
61: if (len < ALLOCA_LIMIT)
62: wformat = (wchar_t *) alloca (len * sizeof (wchar_t));
63: else
64: {
65: if (wformat != NULL && len / 2 < ALLOCA_LIMIT)
66: wformat = NULL;
67:
68: wformat = (wchar_t *) realloc (wformat, len * sizeof (wchar_t));
69:
70: if (wformat == NULL)
71: {
72: fputws_unlocked (L"out of memory\n", stderr);
73: return;
74: }
75: }
76:
77: memset (&st, '\0', sizeof (st));
78: tmp =format;
79: }
80: while ((res = __mbsrtowcs (wformat, &tmp, len, &st)) == len);
81:
82: if (res == (size_t) -1)
83:
84: wformat = (wchar_t *) L"???";
85:
86: __vfwprintf (stderr, wformat, ap);
87: }
88: #endif
89:
90: void
91: vwarnx (const char *format, __gnuc_va_list ap)
92: {
93: flockfile (stderr);
94: #ifdef USE_IN_LIBIO
95: if (_IO_fwide (stderr, 0) > 0)
96: {
97: __fwprintf (stderr, L"%s: ", __progname);
98: convert_and_print (format, ap);
99: putwc_unlocked (L'\n', stderr);
100: }
101: else
102: #endif
103: {
104: fprintf (stderr, "%s: ", __progname);
105: if (format)
106: vfprintf (stderr, format, ap);
107: putc_unlocked ('\n', stderr);
108: }
109: funlockfile (stderr);
110: }
111: libc_hidden_def (vwarnx)
112:
113: void
114: vwarn (const char *format, __gnuc_va_list ap)
115: {
116: int error = errno;
117:
118: flockfile (stderr);
119: #ifdef USE_IN_LIBIO
120: if (_IO_fwide (stderr, 0) > 0)
121: {
122: __fwprintf (stderr, L"%s: ", __progname);
123: if (format)
124: {
125: convert_and_print (format, ap);
126: fputws_unlocked (L": ", stderr);
127: }
128: __set_errno (error);
129: __fwprintf (stderr, L"%m\n");
130: }
131: else
132: #endif
133: {
134: fprintf (stderr, "%s: ", __progname);
135: if (format)
136: {
137: vfprintf (stderr, format, ap);
138: fputs_unlocked (": ", stderr);
139: }
140: __set_errno (error);
141: fprintf (stderr, "%m\n");
142: }
143: funlockfile (stderr);
144: }
145: libc_hidden_def (vwarn)
146:
147:
148: void
149: warn (const char *format, ...)
150: {
151: VA (vwarn (format, ap))
152: }
153: libc_hidden_def (warn)
154:
155: void
156: warnx (const char *format, ...)
157: {
158: VA (vwarnx (format, ap))
159: }
160: libc_hidden_def (warnx)
161:
162: void
163: verr (int status, const char *format, __gnuc_va_list ap)
164: {
165: vwarn (format, ap);
166: exit (status);
167: }
168: libc_hidden_def (verr)
169:
170: void
171: verrx (int status, const char *format, __gnuc_va_list ap)
172: {
173: vwarnx (format, ap);
174: exit (status);
175: }
176: libc_hidden_def (verrx)
177:
178: void
179: err (int status, const char *format, ...)
180: {
181: VA (verr (status, format, ap))
182: }
183:
184: void
185: errx (int status, const char *format, ...)
186: {
187: VA (verrx (status, format, ap))
188: }