Bug Summary

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