log.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /* $OpenBSD$ */
  2. /*
  3. * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
  14. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  15. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. #include <sys/types.h>
  18. #include <errno.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <unistd.h>
  23. #include "tmux.h"
  24. static FILE *log_file;
  25. static int log_level;
  26. static void log_event_cb(int, const char *);
  27. static void log_vwrite(const char *, va_list);
  28. /* Log callback for libevent. */
  29. static void
  30. log_event_cb(__unused int severity, const char *msg)
  31. {
  32. log_debug("%s", msg);
  33. }
  34. /* Increment log level. */
  35. void
  36. log_add_level(void)
  37. {
  38. log_level++;
  39. }
  40. /* Get log level. */
  41. int
  42. log_get_level(void)
  43. {
  44. return (log_level);
  45. }
  46. /* Open logging to file. */
  47. void
  48. log_open(const char *name)
  49. {
  50. char *path;
  51. if (log_level == 0)
  52. return;
  53. if (log_file != NULL)
  54. fclose(log_file);
  55. xasprintf(&path, "tmate-%s-%ld.log", name, (long)getpid());
  56. log_file = fopen(path, "w");
  57. free(path);
  58. if (log_file == NULL)
  59. return;
  60. setvbuf(log_file, NULL, _IOLBF, 0);
  61. event_set_log_callback(log_event_cb);
  62. }
  63. /* Close logging. */
  64. void
  65. log_close(void)
  66. {
  67. if (log_file != NULL)
  68. fclose(log_file);
  69. log_file = NULL;
  70. event_set_log_callback(NULL);
  71. }
  72. /* Write a log message. */
  73. static void
  74. log_vwrite(const char *msg, va_list ap)
  75. {
  76. char *fmt, *out;
  77. struct timeval tv;
  78. if (log_file == NULL)
  79. return;
  80. if (vasprintf(&fmt, msg, ap) == -1)
  81. exit(1);
  82. if (stravis(&out, fmt, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL) == -1)
  83. exit(1);
  84. gettimeofday(&tv, NULL);
  85. if (fprintf(log_file, "%lld.%06d %s\n", (long long)tv.tv_sec,
  86. (int)tv.tv_usec, out) == -1)
  87. exit(1);
  88. fflush(log_file);
  89. free(out);
  90. free(fmt);
  91. }
  92. /* Log a debug message. */
  93. void
  94. log_debug(const char *msg, ...)
  95. {
  96. va_list ap;
  97. va_start(ap, msg);
  98. log_vwrite(msg, ap);
  99. va_end(ap);
  100. }
  101. /* Log a critical error with error string and die. */
  102. __dead void
  103. fatal(const char *msg, ...)
  104. {
  105. char *fmt;
  106. va_list ap;
  107. va_start(ap, msg);
  108. if (asprintf(&fmt, "fatal: %s: %s", msg, strerror(errno)) == -1)
  109. exit(1);
  110. log_vwrite(fmt, ap);
  111. exit(1);
  112. }
  113. /* Log a critical error and die. */
  114. __dead void
  115. fatalx(const char *msg, ...)
  116. {
  117. char *fmt;
  118. va_list ap;
  119. va_start(ap, msg);
  120. if (asprintf(&fmt, "fatal: %s", msg) == -1)
  121. exit(1);
  122. log_vwrite(fmt, ap);
  123. exit(1);
  124. }