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