log.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2014 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #include <fcntl.h>
  14. #include <stdarg.h>
  15. #include <stdio.h>
  16. #include <stdint.h>
  17. #include <stdlib.h>
  18. #include <unistd.h>
  19. #include <stdbool.h>
  20. #include <time.h>
  21. #include <sys/uio.h>
  22. #include <sys/types.h>
  23. #include <sys/socket.h>
  24. #include <sys/un.h>
  25. #include "src/log.h"
  26. #define LOG_TAG "bluetoothd"
  27. #define LOG_DEBUG 3
  28. #define LOG_INFO 4
  29. #define LOG_WARN 5
  30. #define LOG_ERR 6
  31. #define LOG_ID_SYSTEM 3
  32. struct logd_header {
  33. uint8_t id;
  34. uint16_t pid; /* Android logd expects only 2 bytes for PID */
  35. uint32_t sec;
  36. uint32_t nsec;
  37. } __attribute__ ((packed));
  38. static int log_fd = -1;
  39. static bool legacy_log = false;
  40. static void android_log(unsigned char level, const char *fmt, va_list ap)
  41. {
  42. struct logd_header header;
  43. struct iovec vec[4];
  44. int cnt = 0;
  45. char *msg;
  46. static pid_t pid = 0;
  47. if (log_fd < 0)
  48. return;
  49. /* no need to call getpid all the time since we don't fork */
  50. if (!pid)
  51. pid = getpid();
  52. if (vasprintf(&msg, fmt, ap) < 0)
  53. return;
  54. if (!legacy_log) {
  55. struct timespec ts;
  56. clock_gettime(CLOCK_REALTIME, &ts);
  57. header.id = LOG_ID_SYSTEM;
  58. header.pid = pid;
  59. header.sec = ts.tv_sec;
  60. header.nsec = ts.tv_nsec;
  61. vec[0].iov_base = &header;
  62. vec[0].iov_len = sizeof(header);
  63. cnt += 1;
  64. }
  65. vec[cnt + 0].iov_base = &level;
  66. vec[cnt + 0].iov_len = sizeof(level);
  67. vec[cnt + 1].iov_base = LOG_TAG;
  68. vec[cnt + 1].iov_len = sizeof(LOG_TAG);
  69. vec[cnt + 2].iov_base = msg;
  70. vec[cnt + 2].iov_len = strlen(msg) + 1;
  71. cnt += 3;
  72. writev(log_fd, vec, cnt);
  73. free(msg);
  74. }
  75. void info(const char *format, ...)
  76. {
  77. va_list ap;
  78. va_start(ap, format);
  79. android_log(LOG_INFO, format, ap);
  80. va_end(ap);
  81. }
  82. void warn(const char *format, ...)
  83. {
  84. va_list ap;
  85. va_start(ap, format);
  86. android_log(LOG_WARN, format, ap);
  87. va_end(ap);
  88. }
  89. void error(const char *format, ...)
  90. {
  91. va_list ap;
  92. va_start(ap, format);
  93. android_log(LOG_ERR, format, ap);
  94. va_end(ap);
  95. }
  96. void btd_debug(uint16_t index, const char *format, ...)
  97. {
  98. va_list ap;
  99. va_start(ap, format);
  100. android_log(LOG_DEBUG, format, ap);
  101. va_end(ap);
  102. }
  103. static bool init_legacy_log(void)
  104. {
  105. log_fd = open("/dev/log/system", O_WRONLY);
  106. if (log_fd < 0)
  107. return false;
  108. legacy_log = true;
  109. return true;
  110. }
  111. static bool init_logd(void)
  112. {
  113. struct sockaddr_un addr;
  114. log_fd = socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
  115. if (log_fd < 0)
  116. return false;
  117. if (fcntl(log_fd, F_SETFL, O_NONBLOCK) < 0)
  118. goto failed;
  119. memset(&addr, 0, sizeof(addr));
  120. addr.sun_family = AF_UNIX;
  121. strcpy(addr.sun_path, "/dev/socket/logdw");
  122. if (connect(log_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
  123. goto failed;
  124. return true;
  125. failed:
  126. close(log_fd);
  127. log_fd = -1;
  128. return false;
  129. }
  130. extern struct btd_debug_desc __start___debug[];
  131. extern struct btd_debug_desc __stop___debug[];
  132. void __btd_log_init(const char *debug, int detach)
  133. {
  134. if (!init_logd() && !init_legacy_log())
  135. return;
  136. if (debug) {
  137. struct btd_debug_desc *desc;
  138. for (desc = __start___debug; desc < __stop___debug; desc++)
  139. desc->flags |= BTD_DEBUG_FLAG_PRINT;
  140. }
  141. info("Bluetooth daemon %s", VERSION);
  142. }
  143. void __btd_log_cleanup(void)
  144. {
  145. if (log_fd < 0)
  146. return;
  147. close(log_fd);
  148. log_fd = -1;
  149. }