]> git.ipfire.org Git - thirdparty/cups.git/blame - filter/error.c
Full sweep of all Clang warnings, plus some bug fixes for incorrect memcpy usage.
[thirdparty/cups.git] / filter / error.c
CommitLineData
f7deaa1a 1/*
f2d18633 2 * "$Id$"
f7deaa1a 3 *
7e86f2f6 4 * Raster error handling for CUPS.
f7deaa1a 5 *
7e86f2f6
MS
6 * Copyright 2007-2014 by Apple Inc.
7 * Copyright 2007 by Easy Software Products.
f7deaa1a 8 *
7e86f2f6
MS
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
f7deaa1a 14 *
7e86f2f6 15 * This file is subject to the Apple OS-Developed Software exception.
f7deaa1a 16 */
17
18/*
19 * Include necessary headers...
20 */
21
a4845881 22#include <cups/raster-private.h>
f7deaa1a 23
24
25/*
26 * Local structures...
27 */
28
29typedef struct _cups_raster_error_s /**** Error buffer structure ****/
30{
31 char *start, /* Start of buffer */
32 *current, /* Current position in buffer */
33 *end; /* End of buffer */
34} _cups_raster_error_t;
35
36
37/*
38 * Local functions...
39 */
40
41static _cups_raster_error_t *get_error_buffer(void);
42
43
44/*
45 * '_cupsRasterAddError()' - Add an error message to the error buffer.
46 */
47
48void
49_cupsRasterAddError(const char *f, /* I - Printf-style error message */
50 ...) /* I - Additional arguments as needed */
51{
52 _cups_raster_error_t *buf = get_error_buffer();
53 /* Error buffer */
54 va_list ap; /* Pointer to additional arguments */
55 char s[2048]; /* Message string */
7e86f2f6 56 ssize_t bytes; /* Bytes in message string */
f7deaa1a 57
58
59 va_start(ap, f);
60 bytes = vsnprintf(s, sizeof(s), f, ap);
61 va_end(ap);
62
63 if (bytes <= 0)
64 return;
65
66 bytes ++;
67
7e86f2f6 68 if ((size_t)bytes >= sizeof(s))
f7deaa1a 69 return;
70
7e86f2f6 71 if (bytes > (ssize_t)(buf->end - buf->current))
f7deaa1a 72 {
73 /*
74 * Allocate more memory...
75 */
76
77 char *temp; /* New buffer */
78 size_t size; /* Size of buffer */
79
80
7e86f2f6 81 size = (size_t)(buf->end - buf->start + 2 * bytes + 1024);
f7deaa1a 82
83 if (buf->start)
84 temp = realloc(buf->start, size);
85 else
86 temp = malloc(size);
87
88 if (!temp)
89 return;
90
91 /*
92 * Update pointers...
93 */
94
95 buf->end = temp + size;
96 buf->current = temp + (buf->current - buf->start);
97 buf->start = temp;
98 }
99
100 /*
101 * Append the message to the end of the current string...
102 */
103
7e86f2f6 104 memcpy(buf->current, s, (size_t)bytes);
f7deaa1a 105 buf->current += bytes - 1;
106}
107
108
109/*
110 * '_cupsRasterClearError()' - Clear the error buffer.
111 */
112
113void
114_cupsRasterClearError(void)
115{
116 _cups_raster_error_t *buf = get_error_buffer();
117 /* Error buffer */
118
119
120 buf->current = buf->start;
121
122 if (buf->start)
123 *(buf->start) = '\0';
124}
125
126
127/*
128 * 'cupsRasterErrorString()' - Return the last error from a raster function.
129 *
130 * If there are no recent errors, NULL is returned.
131 *
f3c17241 132 * @since CUPS 1.3/OS X 10.5@
f7deaa1a 133 */
134
135const char * /* O - Last error */
136cupsRasterErrorString(void)
137{
138 _cups_raster_error_t *buf = get_error_buffer();
139 /* Error buffer */
140
141
142 if (buf->current == buf->start)
143 return (NULL);
144 else
145 return (buf->start);
146}
147
148
149#ifdef HAVE_PTHREAD_H
150/*
151 * Implement per-thread globals...
152 */
153
154# include <pthread.h>
155
156
157/*
158 * Local globals...
159 */
160
7e86f2f6 161static pthread_key_t raster_key = 0; /* Thread local storage key */
f7deaa1a 162static pthread_once_t raster_key_once = PTHREAD_ONCE_INIT;
163 /* One-time initialization object */
164
165
166/*
167 * Local functions...
168 */
169
170static void raster_init(void);
171static void raster_destructor(void *value);
172
173
174/*
175 * 'get_error_buffer()' - Return a pointer to thread local storage.
176 */
177
178_cups_raster_error_t * /* O - Pointer to error buffer */
179get_error_buffer(void)
180{
181 _cups_raster_error_t *buf; /* Pointer to error buffer */
182
183
321d8d57 184 /*
f7deaa1a 185 * Initialize the global data exactly once...
186 */
187
ae71f5de 188 DEBUG_puts("get_error_buffer()");
f7deaa1a 189
190 pthread_once(&raster_key_once, raster_init);
191
192 /*
193 * See if we have allocated the data yet...
194 */
195
196 if ((buf = (_cups_raster_error_t *)pthread_getspecific(raster_key))
197 == NULL)
198 {
199 DEBUG_puts("get_error_buffer: allocating memory for thread...");
200
201 /*
202 * No, allocate memory as set the pointer for the key...
203 */
204
205 buf = calloc(1, sizeof(_cups_raster_error_t));
206 pthread_setspecific(raster_key, buf);
207
208 DEBUG_printf((" buf=%p\n", buf));
209 }
210
211 /*
212 * Return the pointer to the data...
213 */
214
215 return (buf);
216}
217
218
219/*
220 * 'raster_init()' - Initialize error buffer once.
221 */
222
223static void
224raster_init(void)
225{
226 pthread_key_create(&raster_key, raster_destructor);
227
ae71f5de
MS
228 DEBUG_printf(("raster_init(): raster_key=%x(%u)\n", (unsigned)raster_key,
229 (unsigned)raster_key));
f7deaa1a 230}
231
232
233/*
234 * 'raster_destructor()' - Free memory allocated by get_error_buffer().
235 */
236
237static void
238raster_destructor(void *value) /* I - Data to free */
239{
240 _cups_raster_error_t *buf = (_cups_raster_error_t *)value;
241 /* Error buffer */
242
243
244 DEBUG_printf(("raster_destructor(value=%p)\n", value));
245
246 if (buf->start)
247 free(buf->start);
248
249 free(value);
250}
251
252
253#else
254/*
255 * Implement static globals...
256 */
257
258/*
259 * 'get_error_buffer()' - Return a pointer to thread local storage.
260 */
261
262_cups_raster_error_t * /* O - Pointer to error buffer */
263get_error_buffer(void)
264{
265 static _cups_raster_error_t buf = { 0, 0, 0 };
266 /* Error buffer */
267
268
269 return (&buf);
270}
271#endif /* HAVE_PTHREAD_H */
272
273
274/*
f2d18633 275 * End of "$Id$".
f7deaa1a 276 */