Bug Summary

File:rpmio/rpmlog.c
Warning:line 313, column 2
Value stored to 'n' is never read

Annotated Source Code

1/** \ingroup rpmio
2 * \file rpmio/rpmlog.c
3 */
4
5#include "system.h"
6#include <stdarg.h>
7#include <stdlib.h>
8#include <pthread.h>
9#include <errno(*__errno_location ()).h>
10#include <rpm/rpmlog.h>
11#include "debug.h"
12
13typedef struct rpmlogCtx_s * rpmlogCtx;
14struct rpmlogCtx_s {
15 pthread_rwlock_t lock;
16 unsigned mask;
17 int nrecs;
18 rpmlogRec recs;
19 rpmlogCallback cbfunc;
20 rpmlogCallbackData cbdata;
21 FILE *stdlog;
22};
23
24struct rpmlogRec_s {
25 int code; /* unused */
26 rpmlogLvl pri; /* priority */
27 char * message; /* log message string */
28};
29
30/* Force log context acquisition through a function */
31static rpmlogCtx rpmlogCtxAcquire(int write)
32{
33 static struct rpmlogCtx_s _globalCtx = { PTHREAD_RWLOCK_INITIALIZER{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0 }, 0, 0 }
}
,
34 RPMLOG_UPTO(RPMLOG_NOTICE)((1 << (((unsigned)(RPMLOG_NOTICE))+1)) - 1),
35 0, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0) };
36 rpmlogCtx ctx = &_globalCtx;
37 int xx;
38
39 /* XXX Silently failing is bad, but we can't very well use log here... */
40 if (write)
41 xx = pthread_rwlock_wrlock(&ctx->lock);
42 else
43 xx = pthread_rwlock_rdlock(&ctx->lock);
44
45 return (xx == 0) ? ctx : NULL((void*)0);
46}
47
48/* Release log context */
49static rpmlogCtx rpmlogCtxRelease(rpmlogCtx ctx)
50{
51 if (ctx)
52 pthread_rwlock_unlock(&ctx->lock);
53 return NULL((void*)0);
54}
55
56int rpmlogGetNrecs(void)
57{
58 rpmlogCtx ctx = rpmlogCtxAcquire(0);
59 int nrecs = -1;
60 if (ctx)
61 nrecs = ctx->nrecs;
62 rpmlogCtxRelease(ctx);
63 return nrecs;
64}
65
66int rpmlogCode(void)
67{
68 int code = -1;
69 rpmlogCtx ctx = rpmlogCtxAcquire(0);
70
71 if (ctx && ctx->recs != NULL((void*)0) && ctx->nrecs > 0)
72 code = ctx->recs[ctx->nrecs-1].code;
73
74 rpmlogCtxRelease(ctx);
75 return code;
76}
77
78const char * rpmlogMessage(void)
79{
80 const char *msg = _("(no error)")dcgettext ("rpm", "(no error)", 5);
81 rpmlogCtx ctx = rpmlogCtxAcquire(0);
82
83 if (ctx && ctx->recs != NULL((void*)0) && ctx->nrecs > 0)
84 msg = ctx->recs[ctx->nrecs-1].message;
85
86 rpmlogCtxRelease(ctx);
87 return msg;
88}
89
90const char * rpmlogRecMessage(rpmlogRec rec)
91{
92 return (rec != NULL((void*)0)) ? rec->message : NULL((void*)0);
93}
94
95rpmlogLvl rpmlogRecPriority(rpmlogRec rec)
96{
97 return (rec != NULL((void*)0)) ? rec->pri : (rpmlogLvl)-1;
98}
99
100void rpmlogPrint(FILE *f)
101{
102 rpmlogCtx ctx = rpmlogCtxAcquire(0);
103
104 if (ctx == NULL((void*)0))
105 return;
106
107 if (f == NULL((void*)0))
108 f = stderrstderr;
109
110 for (int i = 0; i < ctx->nrecs; i++) {
111 rpmlogRec rec = ctx->recs + i;
112 if (rec->message && *rec->message)
113 fprintf(f, " %s", rec->message);
114 }
115
116 rpmlogCtxRelease(ctx);
117}
118
119void rpmlogClose (void)
120{
121 rpmlogCtx ctx = rpmlogCtxAcquire(1);
122
123 if (ctx == NULL((void*)0))
124 return;
125
126 for (int i = 0; i < ctx->nrecs; i++) {
127 rpmlogRec rec = ctx->recs + i;
128 rec->message = _free(rec->message)rfree((rec->message));
129 }
130 ctx->recs = _free(ctx->recs)rfree((ctx->recs));
131 ctx->nrecs = 0;
132
133 rpmlogCtxRelease(ctx);
134}
135
136void rpmlogOpen (const char *ident, int option,
137 int facility)
138{
139}
140
141#ifdef NOTYET
142static unsigned rpmlogFacility = RPMLOG_USER;
143#endif
144
145int rpmlogSetMask (int mask)
146{
147 rpmlogCtx ctx = rpmlogCtxAcquire(mask ? 1 : 0);
148
149 int omask = -1;
150 if (ctx) {
151 omask = ctx->mask;
152 if (mask)
153 ctx->mask = mask;
154 }
155
156 rpmlogCtxRelease(ctx);
157 return omask;
158}
159
160rpmlogCallback rpmlogSetCallback(rpmlogCallback cb, rpmlogCallbackData data)
161{
162 rpmlogCtx ctx = rpmlogCtxAcquire(1);
163
164 rpmlogCallback ocb = NULL((void*)0);
165 if (ctx) {
166 ocb = ctx->cbfunc;
167 ctx->cbfunc = cb;
168 ctx->cbdata = data;
169 }
170
171 rpmlogCtxRelease(ctx);
172 return ocb;
173}
174
175static int rpmlogDefault(FILE *stdlog, rpmlogRec rec)
176{
177 FILE *msgout = (stdlog ? stdlog : stderrstderr);
178
179 switch (rec->pri) {
180 case RPMLOG_INFO:
181 case RPMLOG_NOTICE:
182 msgout = (stdlog ? stdlog : stdoutstdout);
183 break;
184 case RPMLOG_EMERG:
185 case RPMLOG_ALERT:
186 case RPMLOG_CRIT:
187 case RPMLOG_ERR:
188 case RPMLOG_WARNING:
189 case RPMLOG_DEBUG:
190 default:
191 break;
192 }
193
194 if (fputs(rpmlogLevelPrefix(rec->pri), msgout) == EOF(-1) && errno(*__errno_location ()) != EPIPE32)
195 perror("Error occurred during writing of a log message");
196
197 if (fputs(rec->message, msgout) == EOF(-1) && errno(*__errno_location ()) != EPIPE32)
198 perror("Error occurred during writing of a log message");
199
200 if (fflush(msgout) == EOF(-1) && errno(*__errno_location ()) != EPIPE32)
201 perror("Error occurred during writing of a log message");
202
203 return (rec->pri <= RPMLOG_CRIT ? RPMLOG_EXIT0x02 : 0);
204}
205
206
207FILE * rpmlogSetFile(FILE * fp)
208{
209 rpmlogCtx ctx = rpmlogCtxAcquire(1);
210
211 FILE * ofp = NULL((void*)0);
212 if (ctx) {
213 ofp = ctx->stdlog;
214 ctx->stdlog = fp;
215 }
216
217 rpmlogCtxRelease(ctx);
218 return ofp;
219}
220
221static const char * const rpmlogMsgPrefix[] = {
222 N_("fatal error: ")"fatal error: ",/*!< RPMLOG_EMERG */
223 N_("fatal error: ")"fatal error: ",/*!< RPMLOG_ALERT */
224 N_("fatal error: ")"fatal error: ",/*!< RPMLOG_CRIT */
225 N_("error: ")"error: ", /*!< RPMLOG_ERR */
226 N_("warning: ")"warning: ", /*!< RPMLOG_WARNING */
227 "", /*!< RPMLOG_NOTICE */
228 "", /*!< RPMLOG_INFO */
229 "D: ", /*!< RPMLOG_DEBUG */
230};
231
232const char * rpmlogLevelPrefix(rpmlogLvl pri)
233{
234 const char * prefix = "";
235 if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri])
236 prefix = _(rpmlogMsgPrefix[pri])dcgettext ("rpm", rpmlogMsgPrefix[pri], 5);
237 return prefix;
238}
239
240/* FIX: rpmlogMsgPrefix[] dependent, not unqualified */
241/* FIX: rpmlogMsgPrefix[] may be NULL */
242static void dolog(struct rpmlogRec_s *rec, int saverec)
243{
244 static pthread_mutex_t serialize = PTHREAD_MUTEX_INITIALIZER{ { 0, 0, 0, 0, 0, 0, 0, { 0, 0 } } };
245
246 int cbrc = RPMLOG_DEFAULT0x01;
247 int needexit = 0;
248 FILE *clog = NULL((void*)0);
249 rpmlogCallbackData *cbdata = NULL((void*)0);
250 rpmlogCallback cbfunc = NULL((void*)0);
251 rpmlogCtx ctx = rpmlogCtxAcquire(saverec);
252
253 if (ctx == NULL((void*)0))
254 return;
255
256 /* Save copy of all messages at warning (or below == "more important"). */
257 if (saverec) {
258 ctx->recs = xrealloc(ctx->recs, (ctx->nrecs+2) * sizeof(*ctx->recs))rrealloc((ctx->recs), ((ctx->nrecs+2) * sizeof(*ctx->
recs)))
;
259 ctx->recs[ctx->nrecs].code = rec->code;
260 ctx->recs[ctx->nrecs].pri = rec->pri;
261 ctx->recs[ctx->nrecs].message = xstrdup(rec->message)rstrdup((rec->message));
262 ctx->recs[ctx->nrecs+1].code = 0;
263 ctx->recs[ctx->nrecs+1].message = NULL((void*)0);
264 ctx->nrecs++;
265 }
266 cbfunc = ctx->cbfunc;
267 cbdata = ctx->cbdata;
268 clog = ctx->stdlog;
269
270 /* Free the context for callback and actual log output */
271 ctx = rpmlogCtxRelease(ctx);
272
273 /* Always serialize callback and output to avoid interleaved messages. */
274 if (pthread_mutex_lock(&serialize) == 0) {
275 if (cbfunc) {
276 cbrc = cbfunc(rec, cbdata);
277 needexit += cbrc & RPMLOG_EXIT0x02;
278 }
279
280 if (cbrc & RPMLOG_DEFAULT0x01) {
281 cbrc = rpmlogDefault(clog, rec);
282 needexit += cbrc & RPMLOG_EXIT0x02;
283 }
284 pthread_mutex_unlock(&serialize);
285 }
286
287 if (needexit)
288 exit(EXIT_FAILURE1);
289
290}
291
292void rpmlog (int code, const char *fmt, ...)
293{
294 unsigned pri = RPMLOG_PRI(code)((code) & 0x07);
295 unsigned mask = RPMLOG_MASK(pri)(1 << ((unsigned)(pri)));
296 int saverec = (pri <= RPMLOG_WARNING);
297 va_list ap;
298 int n;
299
300 if ((mask & rpmlogSetMask(0)) == 0)
301 return;
302
303 va_start(ap, fmt)__builtin_va_start(ap, fmt);
304 n = vsnprintf(NULL((void*)0), 0, fmt, ap);
305 va_end(ap)__builtin_va_end(ap);
306
307 if (n >= -1) {
308 struct rpmlogRec_s rec;
309 size_t nb = n + 1;
310 char *msg = xmalloc(nb)rmalloc((nb));
311
312 va_start(ap, fmt)__builtin_va_start(ap, fmt);
313 n = vsnprintf(msg, nb, fmt, ap);
Value stored to 'n' is never read
314 va_end(ap)__builtin_va_end(ap);
315
316 rec.code = code;
317 rec.pri = pri;
318 rec.message = msg;
319
320 dolog(&rec, saverec);
321
322 free(msg);
323 }
324}
325