Bug Summary

File:os/log.c
Location:line 765, column 29
Description:The left operand of '==' is a garbage value

Annotated Source Code

1/*
2
3Copyright 1987, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from The Open Group.
26
27Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
28Copyright 1994 Quarterdeck Office Systems.
29
30 All Rights Reserved
31
32Permission to use, copy, modify, and distribute this software and its
33documentation for any purpose and without fee is hereby granted,
34provided that the above copyright notice appear in all copies and that
35both that copyright notice and this permission notice appear in
36supporting documentation, and that the names of Digital and
37Quarterdeck not be used in advertising or publicity pertaining to
38distribution of the software without specific, written prior
39permission.
40
41DIGITAL AND QUARTERDECK DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
42SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
43FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT
44OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
45OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
46OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
47OR PERFORMANCE OF THIS SOFTWARE.
48
49*/
50
51/*
52 * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
53 *
54 * Permission is hereby granted, free of charge, to any person obtaining a
55 * copy of this software and associated documentation files (the "Software"),
56 * to deal in the Software without restriction, including without limitation
57 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
58 * and/or sell copies of the Software, and to permit persons to whom the
59 * Software is furnished to do so, subject to the following conditions:
60 *
61 * The above copyright notice and this permission notice shall be included in
62 * all copies or substantial portions of the Software.
63 *
64 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
65 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
66 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
67 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
68 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
69 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
70 * OTHER DEALINGS IN THE SOFTWARE.
71 *
72 * Except as contained in this notice, the name of the copyright holder(s)
73 * and author(s) shall not be used in advertising or otherwise to promote
74 * the sale, use or other dealings in this Software without prior written
75 * authorization from the copyright holder(s) and author(s).
76 */
77
78#ifdef HAVE_DIX_CONFIG_H1
79#include <dix-config.h>
80#endif
81
82#include <X11/Xos.h>
83#include <stdio.h>
84#include <time.h>
85#include <sys/stat.h>
86#include <stdarg.h>
87#include <stdlib.h> /* for malloc() */
88
89#include "input.h"
90#include "site.h"
91#include "opaque.h"
92
93#ifdef WIN32
94#include <process.h>
95#define getpid(x) _getpid(x)
96#endif
97
98#ifdef XF86BIGFONT
99#include "xf86bigfontsrv.h"
100#endif
101
102#ifdef __clang__1
103#pragma clang diagnostic ignored "-Wformat-nonliteral"
104#endif
105
106#ifdef DDXOSVERRORF
107void (*OsVendorVErrorFProc) (const char *, va_list args) = NULL((void*)0);
108#endif
109
110static FILE *logFile = NULL((void*)0);
111static int logFileFd = -1;
112static Bool logFlush = FALSE0;
113static Bool logSync = FALSE0;
114static int logVerbosity = DEFAULT_LOG_VERBOSITY0;
115static int logFileVerbosity = DEFAULT_LOG_FILE_VERBOSITY3;
116
117/* Buffer to information logged before the log file is opened. */
118static char *saveBuffer = NULL((void*)0);
119static int bufferSize = 0, bufferUnused = 0, bufferPos = 0;
120static Bool needBuffer = TRUE1;
121
122#ifdef __APPLE__1
123#include <AvailabilityMacros.h>
124
125static char __crashreporter_info_buff__[4096] = { 0 };
126
127static const char *__crashreporter_info__ __attribute__ ((__used__)) =
128 &__crashreporter_info_buff__[0];
129#if MAC_OS_X_VERSION_MIN_REQUIRED101100 >= 1050
130// This is actually a toolchain requirement, but I'm not sure the correct check,
131// but it should be fine to just only include it for Leopard and later. This line
132// just tells the linker to never strip this symbol (such as for space optimization)
133asm(".desc ___crashreporter_info__, 0x10");
134#endif
135#endif
136
137/* Prefix strings for log messages. */
138#ifndef X_UNKNOWN_STRING"(\?\?)"
139#define X_UNKNOWN_STRING"(\?\?)" "(\?\?)"
140#endif
141#ifndef X_PROBE_STRING"(--)"
142#define X_PROBE_STRING"(--)" "(--)"
143#endif
144#ifndef X_CONFIG_STRING"(**)"
145#define X_CONFIG_STRING"(**)" "(**)"
146#endif
147#ifndef X_DEFAULT_STRING"(==)"
148#define X_DEFAULT_STRING"(==)" "(==)"
149#endif
150#ifndef X_CMDLINE_STRING"(++)"
151#define X_CMDLINE_STRING"(++)" "(++)"
152#endif
153#ifndef X_NOTICE_STRING"(!!)"
154#define X_NOTICE_STRING"(!!)" "(!!)"
155#endif
156#ifndef X_ERROR_STRING"(EE)"
157#define X_ERROR_STRING"(EE)" "(EE)"
158#endif
159#ifndef X_WARNING_STRING"(WW)"
160#define X_WARNING_STRING"(WW)" "(WW)"
161#endif
162#ifndef X_INFO_STRING"(II)"
163#define X_INFO_STRING"(II)" "(II)"
164#endif
165#ifndef X_NOT_IMPLEMENTED_STRING"(NI)"
166#define X_NOT_IMPLEMENTED_STRING"(NI)" "(NI)"
167#endif
168#ifndef X_DEBUG_STRING"(DB)"
169#define X_DEBUG_STRING"(DB)" "(DB)"
170#endif
171#ifndef X_NONE_STRING""
172#define X_NONE_STRING"" ""
173#endif
174
175static size_t
176strlen_sigsafe(const char *s)
177{
178 size_t len;
179 for (len = 0; s[len]; len++);
180 return len;
181}
182
183/*
184 * LogInit is called to start logging to a file. It is also called (with
185 * NULL arguments) when logging to a file is not wanted. It must always be
186 * called, otherwise log messages will continue to accumulate in a buffer.
187 *
188 * %s, if present in the fname or backup strings, is expanded to the display
189 * string.
190 */
191
192#pragma GCC diagnostic push
193#pragma GCC diagnostic ignored "-Wformat-nonliteral"
194
195const char *
196LogInit(const char *fname, const char *backup)
197{
198 char *logFileName = NULL((void*)0);
199
200 if (fname && *fname) {
201 if (asprintf(&logFileName, fname, display) == -1)
202 FatalError("Cannot allocate space for the log file name\n");
203
204 if (backup && *backup) {
205 struct stat buf;
206
207 if (!stat(logFileName, &buf) && S_ISREG(buf.st_mode)(((buf.st_mode) & 0170000) == 0100000)) {
208 char *suffix;
209 char *oldLog;
210
211 if ((asprintf(&suffix, backup, display) == -1) ||
212 (asprintf(&oldLog, "%s%s", logFileName, suffix) == -1))
213 FatalError("Cannot allocate space for the log file name\n");
214 free(suffix);
215 if (rename(logFileName, oldLog) == -1) {
216 FatalError("Cannot move old log file \"%s\" to \"%s\"\n",
217 logFileName, oldLog);
218 }
219 free(oldLog);
220 }
221 }
222 else {
223 unlink(logFileName);
224 }
225 if ((logFile = fopen(logFileName, "w")) == NULL((void*)0))
226 FatalError("Cannot open log file \"%s\"\n", logFileName);
227 setvbuf(logFile, NULL((void*)0), _IONBF2, 0);
228
229 logFileFd = fileno(logFile);
230
231 /* Flush saved log information. */
232 if (saveBuffer && bufferSize > 0) {
233 fwrite(saveBuffer, bufferPos, 1, logFile);
234 fflush(logFile);
235#ifndef WIN32
236 fsync(fileno(logFile));
237#endif
238 }
239 }
240
241 /*
242 * Unconditionally free the buffer, and flag that the buffer is no longer
243 * needed.
244 */
245 if (saveBuffer && bufferSize > 0) {
246 free(saveBuffer);
247 saveBuffer = NULL((void*)0);
248 bufferSize = 0;
249 }
250 needBuffer = FALSE0;
251
252 return logFileName;
253}
254#pragma GCC diagnostic pop
255
256void
257LogClose(enum ExitCode error)
258{
259 if (logFile) {
260 int msgtype = (error == EXIT_NO_ERROR) ? X_INFO : X_ERROR;
261 LogMessageVerbSigSafe(msgtype, -1,
262 "Server terminated %s (%d). Closing log file.\n",
263 (error == EXIT_NO_ERROR) ? "successfully" : "with error",
264 error);
265 fclose(logFile);
266 logFile = NULL((void*)0);
267 logFileFd = -1;
268 }
269}
270
271Bool
272LogSetParameter(LogParameter param, int value)
273{
274 switch (param) {
275 case XLOG_FLUSH:
276 logFlush = value ? TRUE1 : FALSE0;
277 return TRUE1;
278 case XLOG_SYNC:
279 logSync = value ? TRUE1 : FALSE0;
280 return TRUE1;
281 case XLOG_VERBOSITY:
282 logVerbosity = value;
283 return TRUE1;
284 case XLOG_FILE_VERBOSITY:
285 logFileVerbosity = value;
286 return TRUE1;
287 default:
288 return FALSE0;
289 }
290}
291
292enum {
293 LMOD_LONG = 0x1,
294 LMOD_LONGLONG = 0x2,
295 LMOD_SHORT = 0x4,
296 LMOD_SIZET = 0x8,
297};
298
299/**
300 * Parse non-digit length modifiers and set the corresponding flag in
301 * flags_return.
302 *
303 * @return the number of bytes parsed
304 */
305static int parse_length_modifier(const char *format, size_t len, int *flags_return)
306{
307 int idx = 0;
308 int length_modifier = 0;
309
310 while (idx < len) {
311 switch (format[idx]) {
312 case 'l':
313 BUG_RETURN_VAL(length_modifier & LMOD_SHORT, 0)do { if (length_modifier & LMOD_SHORT) { do { if (length_modifier
& LMOD_SHORT) { ErrorFSigSafe("BUG: triggered 'if (" "length_modifier & LMOD_SHORT"
")'\n"); ErrorFSigSafe("BUG: %s:%u in %s()\n", "log.c", 313,
__func__); if (0) ErrorFSigSafe(((void*)0)); xorg_backtrace(
); } } while(0); return (0); } } while(0)
;
314
315 if (length_modifier & LMOD_LONG)
316 length_modifier |= LMOD_LONGLONG;
317 else
318 length_modifier |= LMOD_LONG;
319 break;
320 case 'h':
321 BUG_RETURN_VAL(length_modifier & (LMOD_LONG|LMOD_LONGLONG), 0)do { if (length_modifier & (LMOD_LONG|LMOD_LONGLONG)) { do
{ if (length_modifier & (LMOD_LONG|LMOD_LONGLONG)) { ErrorFSigSafe
("BUG: triggered 'if (" "length_modifier & (LMOD_LONG|LMOD_LONGLONG)"
")'\n"); ErrorFSigSafe("BUG: %s:%u in %s()\n", "log.c", 321,
__func__); if (0) ErrorFSigSafe(((void*)0)); xorg_backtrace(
); } } while(0); return (0); } } while(0)
;
322 length_modifier |= LMOD_SHORT;
323 /* gcc says 'short int' is promoted to 'int' when
324 * passed through '...', so ignored during
325 * processing */
326 break;
327 case 'z':
328 length_modifier |= LMOD_SIZET;
329 break;
330 default:
331 goto out;
332 }
333 idx++;
334 }
335
336out:
337 *flags_return = length_modifier;
338 return idx;
339}
340
341/**
342 * Signal-safe snprintf, with some limitations over snprintf. Be careful
343 * which directives you use.
344 */
345static int
346vpnprintf(char *string, int size_in, const char *f, va_list args)
347{
348 int f_idx = 0;
349 int s_idx = 0;
350 int f_len = strlen_sigsafe(f);
351 char *string_arg;
352 char number[21];
353 int p_len;
354 int i;
355 uint64_t ui;
356 int64_t si;
357 size_t size = size_in;
358 int precision;
359
360 for (; f_idx < f_len && s_idx < size - 1; f_idx++) {
361 int length_modifier = 0;
362 if (f[f_idx] != '%') {
363 string[s_idx++] = f[f_idx];
364 continue;
365 }
366
367 f_idx++;
368
369 /* silently swallow minimum field width */
370 if (f[f_idx] == '*') {
371 f_idx++;
372 va_arg(args, int)__builtin_va_arg(args, int);
373 } else {
374 while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9')))
375 f_idx++;
376 }
377
378 /* is there a precision? */
379 precision = size;
380 if (f[f_idx] == '.') {
381 f_idx++;
382 if (f[f_idx] == '*') {
383 f_idx++;
384 /* precision is supplied in an int argument */
385 precision = va_arg(args, int)__builtin_va_arg(args, int);
386 } else {
387 /* silently swallow precision digits */
388 while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9')))
389 f_idx++;
390 }
391 }
392
393 /* non-digit length modifiers */
394 if (f_idx < f_len) {
395 int parsed_bytes = parse_length_modifier(&f[f_idx], f_len - f_idx, &length_modifier);
396 if (parsed_bytes < 0)
397 return 0;
398 f_idx += parsed_bytes;
399 }
400
401 if (f_idx >= f_len)
402 break;
403
404 switch (f[f_idx]) {
405 case 's':
406 string_arg = va_arg(args, char*)__builtin_va_arg(args, char*);
407
408 for (i = 0; string_arg[i] != 0 && s_idx < size - 1 && s_idx < precision; i++)
409 string[s_idx++] = string_arg[i];
410 break;
411
412 case 'u':
413 if (length_modifier & LMOD_LONGLONG)
414 ui = va_arg(args, unsigned long long)__builtin_va_arg(args, unsigned long long);
415 else if (length_modifier & LMOD_LONG)
416 ui = va_arg(args, unsigned long)__builtin_va_arg(args, unsigned long);
417 else if (length_modifier & LMOD_SIZET)
418 ui = va_arg(args, size_t)__builtin_va_arg(args, size_t);
419 else
420 ui = va_arg(args, unsigned)__builtin_va_arg(args, unsigned);
421
422 FormatUInt64(ui, number);
423 p_len = strlen_sigsafe(number);
424
425 for (i = 0; i < p_len && s_idx < size - 1; i++)
426 string[s_idx++] = number[i];
427 break;
428 case 'i':
429 case 'd':
430 if (length_modifier & LMOD_LONGLONG)
431 si = va_arg(args, long long)__builtin_va_arg(args, long long);
432 else if (length_modifier & LMOD_LONG)
433 si = va_arg(args, long)__builtin_va_arg(args, long);
434 else if (length_modifier & LMOD_SIZET)
435 si = va_arg(args, ssize_t)__builtin_va_arg(args, ssize_t);
436 else
437 si = va_arg(args, int)__builtin_va_arg(args, int);
438
439 FormatInt64(si, number);
440 p_len = strlen_sigsafe(number);
441
442 for (i = 0; i < p_len && s_idx < size - 1; i++)
443 string[s_idx++] = number[i];
444 break;
445
446 case 'p':
447 string[s_idx++] = '0';
448 if (s_idx < size - 1)
449 string[s_idx++] = 'x';
450 ui = (uintptr_t)va_arg(args, void*)__builtin_va_arg(args, void*);
451 FormatUInt64Hex(ui, number);
452 p_len = strlen_sigsafe(number);
453
454 for (i = 0; i < p_len && s_idx < size - 1; i++)
455 string[s_idx++] = number[i];
456 break;
457
458 case 'x':
459 if (length_modifier & LMOD_LONGLONG)
460 ui = va_arg(args, unsigned long long)__builtin_va_arg(args, unsigned long long);
461 else if (length_modifier & LMOD_LONG)
462 ui = va_arg(args, unsigned long)__builtin_va_arg(args, unsigned long);
463 else if (length_modifier & LMOD_SIZET)
464 ui = va_arg(args, size_t)__builtin_va_arg(args, size_t);
465 else
466 ui = va_arg(args, unsigned)__builtin_va_arg(args, unsigned);
467
468 FormatUInt64Hex(ui, number);
469 p_len = strlen_sigsafe(number);
470
471 for (i = 0; i < p_len && s_idx < size - 1; i++)
472 string[s_idx++] = number[i];
473 break;
474 case 'f':
475 {
476 double d = va_arg(args, double)__builtin_va_arg(args, double);
477 FormatDouble(d, number);
478 p_len = strlen_sigsafe(number);
479
480 for (i = 0; i < p_len && s_idx < size - 1; i++)
481 string[s_idx++] = number[i];
482 }
483 break;
484 case 'c':
485 {
486 char c = va_arg(args, int)__builtin_va_arg(args, int);
487 if (s_idx < size - 1)
488 string[s_idx++] = c;
489 }
490 break;
491 case '%':
492 string[s_idx++] = '%';
493 break;
494 default:
495 BUG_WARN_MSG(f[f_idx], "Unsupported printf directive '%c'\n", f[f_idx])do { if (f[f_idx]) { ErrorFSigSafe("BUG: triggered 'if (" "f[f_idx]"
")'\n"); ErrorFSigSafe("BUG: %s:%u in %s()\n", "log.c", 495,
__func__); if (1) ErrorFSigSafe("Unsupported printf directive '%c'\n"
, f[f_idx]); xorg_backtrace(); } } while(0)
;
496 va_arg(args, char*)__builtin_va_arg(args, char*);
497 string[s_idx++] = '%';
498 if (s_idx < size - 1)
499 string[s_idx++] = f[f_idx];
500 break;
501 }
502 }
503
504 string[s_idx] = '\0';
505
506 return s_idx;
507}
508
509static int
510pnprintf(char *string, int size, const char *f, ...)
511{
512 int rc;
513 va_list args;
514
515 va_start(args, f)__builtin_va_start(args, f);
516 rc = vpnprintf(string, size, f, args);
517 va_end(args)__builtin_va_end(args);
518
519 return rc;
520}
521
522/* This function does the actual log message writes. It must be signal safe.
523 * When attempting to call non-signal-safe functions, guard them with a check
524 * of the inSignalContext global variable. */
525static void
526LogSWrite(int verb, const char *buf, size_t len, Bool end_line)
527{
528 static Bool newline = TRUE1;
529 int ret;
530
531 if (verb < 0 || logVerbosity >= verb)
532 ret = write(2, buf, len);
533
534 if (verb < 0 || logFileVerbosity >= verb) {
535 if (inSignalContext && logFileFd >= 0) {
536 ret = write(logFileFd, buf, len);
537#ifndef WIN32
538 if (logFlush && logSync)
539 fsync(logFileFd);
540#endif
541 }
542 else if (!inSignalContext && logFile) {
543 if (newline)
544 fprintf(logFile, "[%10.3f] ", GetTimeInMillis() / 1000.0);
545 newline = end_line;
546 fwrite(buf, len, 1, logFile);
547 if (logFlush) {
548 fflush(logFile);
549#ifndef WIN32
550 if (logSync)
551 fsync(fileno(logFile));
552#endif
553 }
554 }
555 else if (!inSignalContext && needBuffer) {
556 if (len > bufferUnused) {
557 bufferSize += 1024;
558 bufferUnused += 1024;
559 saveBuffer = realloc(saveBuffer, bufferSize);
560 if (!saveBuffer)
561 FatalError("realloc() failed while saving log messages\n");
562 }
563 bufferUnused -= len;
564 memcpy(saveBuffer + bufferPos, buf, len)__builtin___memcpy_chk (saveBuffer + bufferPos, buf, len, __builtin_object_size
(saveBuffer + bufferPos, 0))
;
565 bufferPos += len;
566 }
567 }
568
569 /* There's no place to log an error message if the log write
570 * fails...
571 */
572 (void) ret;
573}
574
575void
576LogVWrite(int verb, const char *f, va_list args)
577{
578 return LogVMessageVerb(X_NONE, verb, f, args);
579}
580
581void
582LogWrite(int verb, const char *f, ...)
583{
584 va_list args;
585
586 va_start(args, f)__builtin_va_start(args, f);
587 LogVWrite(verb, f, args);
588 va_end(args)__builtin_va_end(args);
589}
590
591/* Returns the Message Type string to prepend to a logging message, or NULL
592 * if the message will be dropped due to insufficient verbosity. */
593static const char *
594LogMessageTypeVerbString(MessageType type, int verb)
595{
596 if (type == X_ERROR)
597 verb = 0;
598
599 if (logVerbosity < verb && logFileVerbosity < verb)
600 return NULL((void*)0);
601
602 switch (type) {
603 case X_PROBED:
604 return X_PROBE_STRING"(--)";
605 case X_CONFIG:
606 return X_CONFIG_STRING"(**)";
607 case X_DEFAULT:
608 return X_DEFAULT_STRING"(==)";
609 case X_CMDLINE:
610 return X_CMDLINE_STRING"(++)";
611 case X_NOTICE:
612 return X_NOTICE_STRING"(!!)";
613 case X_ERROR:
614 return X_ERROR_STRING"(EE)";
615 case X_WARNING:
616 return X_WARNING_STRING"(WW)";
617 case X_INFO:
618 return X_INFO_STRING"(II)";
619 case X_NOT_IMPLEMENTED:
620 return X_NOT_IMPLEMENTED_STRING"(NI)";
621 case X_UNKNOWN:
622 return X_UNKNOWN_STRING"(\?\?)";
623 case X_NONE:
624 return X_NONE_STRING"";
625 case X_DEBUG:
626 return X_DEBUG_STRING"(DB)";
627 default:
628 return X_UNKNOWN_STRING"(\?\?)";
629 }
630}
631
632void
633LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
634{
635 const char *type_str;
636 char buf[1024];
637 const size_t size = sizeof(buf);
638 Bool newline;
639 size_t len = 0;
640
641 if (inSignalContext) {
642 LogVMessageVerbSigSafe(type, verb, format, args);
643 return;
644 }
645
646 type_str = LogMessageTypeVerbString(type, verb);
647 if (!type_str)
648 return;
649
650 /* if type_str is not "", prepend it and ' ', to message */
651 if (type_str[0] != '\0')
652 len += Xscnprintf(&buf[len], size - len, "%s ", type_str);
653
654 if (size - len > 1)
655 len += Xvscnprintf(&buf[len], size - len, format, args);
656
657 /* Force '\n' at end of truncated line */
658 if (size - len == 1)
659 buf[len - 1] = '\n';
660
661 newline = (buf[len - 1] == '\n');
662 LogSWrite(verb, buf, len, newline);
663}
664
665/* Log message with verbosity level specified. */
666void
667LogMessageVerb(MessageType type, int verb, const char *format, ...)
668{
669 va_list ap;
670
671 va_start(ap, format)__builtin_va_start(ap, format);
672 LogVMessageVerb(type, verb, format, ap);
673 va_end(ap)__builtin_va_end(ap);
674}
675
676/* Log a message with the standard verbosity level of 1. */
677void
678LogMessage(MessageType type, const char *format, ...)
679{
680 va_list ap;
681
682 va_start(ap, format)__builtin_va_start(ap, format);
683 LogVMessageVerb(type, 1, format, ap);
684 va_end(ap)__builtin_va_end(ap);
685}
686
687/* Log a message using only signal safe functions. */
688void
689LogMessageVerbSigSafe(MessageType type, int verb, const char *format, ...)
690{
691 va_list ap;
692 va_start(ap, format)__builtin_va_start(ap, format);
693 LogVMessageVerbSigSafe(type, verb, format, ap);
694 va_end(ap)__builtin_va_end(ap);
695}
696
697void
698LogVMessageVerbSigSafe(MessageType type, int verb, const char *format, va_list args)
699{
700 const char *type_str;
701 char buf[1024];
702 int len;
703 Bool newline;
704
705 type_str = LogMessageTypeVerbString(type, verb);
706 if (!type_str)
707 return;
708
709 /* if type_str is not "", prepend it and ' ', to message */
710 if (type_str[0] != '\0') {
711 LogSWrite(verb, type_str, strlen_sigsafe(type_str), FALSE0);
712 LogSWrite(verb, " ", 1, FALSE0);
713 }
714
715 len = vpnprintf(buf, sizeof(buf), format, args);
716
717 /* Force '\n' at end of truncated line */
718 if (sizeof(buf) - len == 1)
719 buf[len - 1] = '\n';
720
721 newline = (len > 0 && buf[len - 1] == '\n');
722 LogSWrite(verb, buf, len, newline);
723}
724
725void
726LogVHdrMessageVerb(MessageType type, int verb, const char *msg_format,
727 va_list msg_args, const char *hdr_format, va_list hdr_args)
728{
729 const char *type_str;
730 char buf[1024];
731 const size_t size = sizeof(buf);
732 Bool newline;
733 size_t len = 0;
734 int (*vprintf_func)(char *, int, const char* _X_RESTRICT_KYWDrestrict f, va_list args)
735 _X_ATTRIBUTE_PRINTF(3, 0)__attribute__((__format__(__printf__,3,0)));
736 int (*printf_func)(char *, int, const char* _X_RESTRICT_KYWDrestrict f, ...)
737 _X_ATTRIBUTE_PRINTF(3, 4)__attribute__((__format__(__printf__,3,4)));
738
739 type_str = LogMessageTypeVerbString(type, verb);
740 if (!type_str)
2
Taking false branch
741 return;
742
743 if (inSignalContext) {
3
Assuming 'inSignalContext' is 0
4
Taking false branch
744 vprintf_func = vpnprintf;
745 printf_func = pnprintf;
746 } else {
747 vprintf_func = Xvscnprintf;
748 printf_func = Xscnprintf;
749 }
750
751 /* if type_str is not "", prepend it and ' ', to message */
752 if (type_str[0] != '\0')
5
Taking false branch
753 len += printf_func(&buf[len], size - len, "%s ", type_str);
754
755 if (hdr_format && size - len > 1)
756 len += vprintf_func(&buf[len], size - len, hdr_format, hdr_args);
757
758 if (msg_format && size - len > 1)
759 len += vprintf_func(&buf[len], size - len, msg_format, msg_args);
760
761 /* Force '\n' at end of truncated line */
762 if (size - len == 1)
6
Taking false branch
763 buf[len - 1] = '\n';
764
765 newline = (buf[len - 1] == '\n');
7
The left operand of '==' is a garbage value
766 LogSWrite(verb, buf, len, newline);
767}
768
769void
770LogHdrMessageVerb(MessageType type, int verb, const char *msg_format,
771 va_list msg_args, const char *hdr_format, ...)
772{
773 va_list hdr_args;
774
775 va_start(hdr_args, hdr_format)__builtin_va_start(hdr_args, hdr_format);
776 LogVHdrMessageVerb(type, verb, msg_format, msg_args, hdr_format, hdr_args);
777 va_end(hdr_args)__builtin_va_end(hdr_args);
778}
779
780void
781LogHdrMessage(MessageType type, const char *msg_format, va_list msg_args,
782 const char *hdr_format, ...)
783{
784 va_list hdr_args;
785
786 va_start(hdr_args, hdr_format)__builtin_va_start(hdr_args, hdr_format);
787 LogVHdrMessageVerb(type, 1, msg_format, msg_args, hdr_format, hdr_args);
1
Calling 'LogVHdrMessageVerb'
788 va_end(hdr_args)__builtin_va_end(hdr_args);
789}
790
791void
792AbortServer(void)
793 _X_NORETURN__attribute((noreturn));
794
795void
796AbortServer(void)
797{
798#ifdef XF86BIGFONT
799 XF86BigfontCleanup();
800#endif
801 CloseWellKnownConnections();
802 OsCleanup(TRUE1);
803 AbortDevices();
804 AbortDDX(EXIT_ERR_ABORT);
805 fflush(stderr__stderrp);
806 if (CoreDump)
807 OsAbort();
808 exit(1);
809}
810
811#define AUDIT_PREFIX"AUDIT: %s: %ld: " "AUDIT: %s: %ld: "
812#ifndef AUDIT_TIMEOUT((CARD32)(120 * 1000))
813#define AUDIT_TIMEOUT((CARD32)(120 * 1000)) ((CARD32)(120 * 1000)) /* 2 mn */
814#endif
815
816static int nrepeat = 0;
817static int oldlen = -1;
818static OsTimerPtr auditTimer = NULL((void*)0);
819
820void
821FreeAuditTimer(void)
822{
823 if (auditTimer != NULL((void*)0)) {
824 /* Force output of pending messages */
825 TimerForce(auditTimer);
826 TimerFree(auditTimer);
827 auditTimer = NULL((void*)0);
828 }
829}
830
831static char *
832AuditPrefix(void)
833{
834 time_t tm;
835 char *autime, *s;
836 char *tmpBuf;
837 int len;
838
839 time(&tm);
840 autime = ctime(&tm);
841 if ((s = strchr(autime, '\n')))
842 *s = '\0';
843 len = strlen(AUDIT_PREFIX"AUDIT: %s: %ld: ") + strlen(autime) + 10 + 1;
844 tmpBuf = malloc(len);
845 if (!tmpBuf)
846 return NULL((void*)0);
847 snprintf(tmpBuf, len, AUDIT_PREFIX, autime, (unsigned long) getpid())__builtin___snprintf_chk (tmpBuf, len, 0, __builtin_object_size
(tmpBuf, 2 > 1 ? 1 : 0), "AUDIT: %s: %ld: ", autime, (unsigned
long) getpid())
;
848 return tmpBuf;
849}
850
851void
852AuditF(const char *f, ...)
853{
854 va_list args;
855
856 va_start(args, f)__builtin_va_start(args, f);
857
858 VAuditF(f, args);
859 va_end(args)__builtin_va_end(args);
860}
861
862static CARD32
863AuditFlush(OsTimerPtr timer, CARD32 now, void *arg)
864{
865 char *prefix;
866
867 if (nrepeat > 0) {
868 prefix = AuditPrefix();
869 ErrorF("%slast message repeated %d times\n",
870 prefix != NULL((void*)0) ? prefix : "", nrepeat);
871 nrepeat = 0;
872 free(prefix);
873 return AUDIT_TIMEOUT((CARD32)(120 * 1000));
874 }
875 else {
876 /* if the timer expires without anything to print, flush the message */
877 oldlen = -1;
878 return 0;
879 }
880}
881
882void
883VAuditF(const char *f, va_list args)
884{
885 char *prefix;
886 char buf[1024];
887 int len;
888 static char oldbuf[1024];
889
890 prefix = AuditPrefix();
891 len = vsnprintf(buf, sizeof(buf), f, args)__builtin___vsnprintf_chk (buf, sizeof(buf), 0, __builtin_object_size
(buf, 2 > 1 ? 1 : 0), f, args)
;
892
893 if (len == oldlen && strcmp(buf, oldbuf) == 0) {
894 /* Message already seen */
895 nrepeat++;
896 }
897 else {
898 /* new message */
899 if (auditTimer != NULL((void*)0))
900 TimerForce(auditTimer);
901 ErrorF("%s%s", prefix != NULL((void*)0) ? prefix : "", buf);
902 strlcpy(oldbuf, buf, sizeof(oldbuf))__builtin___strlcpy_chk (oldbuf, buf, sizeof(oldbuf), __builtin_object_size
(oldbuf, 2 > 1 ? 1 : 0))
;
903 oldlen = len;
904 nrepeat = 0;
905 auditTimer = TimerSet(auditTimer, 0, AUDIT_TIMEOUT((CARD32)(120 * 1000)), AuditFlush, NULL((void*)0));
906 }
907 free(prefix);
908}
909
910void
911FatalError(const char *f, ...)
912{
913 va_list args;
914 va_list args2;
915 static Bool beenhere = FALSE0;
916
917 if (beenhere)
918 ErrorFSigSafe("\nFatalError re-entered, aborting\n");
919 else
920 ErrorFSigSafe("\nFatal server error:\n");
921
922 va_start(args, f)__builtin_va_start(args, f);
923
924 /* Make a copy for OsVendorFatalError */
925 va_copy(args2, args)__builtin_va_copy(args2, args);
926
927#ifdef __APPLE__1
928 {
929 va_list apple_args;
930
931 va_copy(apple_args, args)__builtin_va_copy(apple_args, args);
932 (void)vsnprintf(__crashreporter_info_buff__,__builtin___vsnprintf_chk (__crashreporter_info_buff__, sizeof
(__crashreporter_info_buff__), 0, __builtin_object_size (__crashreporter_info_buff__
, 2 > 1 ? 1 : 0), f, apple_args)
933 sizeof(__crashreporter_info_buff__), f, apple_args)__builtin___vsnprintf_chk (__crashreporter_info_buff__, sizeof
(__crashreporter_info_buff__), 0, __builtin_object_size (__crashreporter_info_buff__
, 2 > 1 ? 1 : 0), f, apple_args)
;
934 va_end(apple_args)__builtin_va_end(apple_args);
935 }
936#endif
937 VErrorFSigSafe(f, args);
938 va_end(args)__builtin_va_end(args);
939 ErrorFSigSafe("\n");
940 if (!beenhere)
941 OsVendorFatalError(f, args2);
942 va_end(args2)__builtin_va_end(args2);
943 if (!beenhere) {
944 beenhere = TRUE1;
945 AbortServer();
946 }
947 else
948 OsAbort();
949 /*NOTREACHED*/}
950
951void
952VErrorF(const char *f, va_list args)
953{
954#ifdef DDXOSVERRORF
955 if (OsVendorVErrorFProc)
956 OsVendorVErrorFProc(f, args);
957 else
958 LogVWrite(-1, f, args);
959#else
960 LogVWrite(-1, f, args);
961#endif
962}
963
964void
965ErrorF(const char *f, ...)
966{
967 va_list args;
968
969 va_start(args, f)__builtin_va_start(args, f);
970 VErrorF(f, args);
971 va_end(args)__builtin_va_end(args);
972}
973
974void
975VErrorFSigSafe(const char *f, va_list args)
976{
977 LogVMessageVerbSigSafe(X_ERROR, -1, f, args);
978}
979
980void
981ErrorFSigSafe(const char *f, ...)
982{
983 va_list args;
984
985 va_start(args, f)__builtin_va_start(args, f);
986 VErrorFSigSafe(f, args);
987 va_end(args)__builtin_va_end(args);
988}
989
990void
991LogPrintMarkers(void)
992{
993 /* Show what the message marker symbols mean. */
994 LogWrite(0, "Markers: ");
995 LogMessageVerb(X_PROBED, 0, "probed, ");
996 LogMessageVerb(X_CONFIG, 0, "from config file, ");
997 LogMessageVerb(X_DEFAULT, 0, "default setting,\n\t");
998 LogMessageVerb(X_CMDLINE, 0, "from command line, ");
999 LogMessageVerb(X_NOTICE, 0, "notice, ");
1000 LogMessageVerb(X_INFO, 0, "informational,\n\t");
1001 LogMessageVerb(X_WARNING, 0, "warning, ");
1002 LogMessageVerb(X_ERROR, 0, "error, ");
1003 LogMessageVerb(X_NOT_IMPLEMENTED, 0, "not implemented, ");
1004 LogMessageVerb(X_UNKNOWN, 0, "unknown.\n");
1005}