system-emulator.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2013-2014 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #define _GNU_SOURCE
  14. #include <stdio.h>
  15. #include <errno.h>
  16. #include <unistd.h>
  17. #include <stdlib.h>
  18. #include <signal.h>
  19. #include <string.h>
  20. #include <libgen.h>
  21. #include <poll.h>
  22. #include <sys/wait.h>
  23. #include <sys/param.h>
  24. #include <sys/socket.h>
  25. #include <sys/un.h>
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #ifndef WAIT_ANY
  29. #define WAIT_ANY (-1)
  30. #endif
  31. #include "src/shared/mainloop.h"
  32. static char exec_dir[PATH_MAX];
  33. static pid_t daemon_pid = -1;
  34. static pid_t snoop_pid = -1;
  35. static void run_valgrind(char *prg_name)
  36. {
  37. char *prg_argv[6];
  38. char *prg_envp[3];
  39. prg_argv[0] = "/usr/bin/valgrind";
  40. prg_argv[1] = "--leak-check=full";
  41. prg_argv[2] = "--track-origins=yes";
  42. prg_argv[3] = prg_name;
  43. prg_argv[4] = "-d";
  44. prg_argv[5] = NULL;
  45. prg_envp[0] = "G_SLICE=always-malloc";
  46. prg_envp[1] = "G_DEBUG=gc-friendly";
  47. prg_envp[2] = NULL;
  48. execve(prg_argv[0], prg_argv, prg_envp);
  49. }
  50. static void run_bluetoothd(char *prg_name)
  51. {
  52. char *prg_argv[3];
  53. char *prg_envp[1];
  54. prg_argv[0] = prg_name;
  55. prg_argv[1] = "-d";
  56. prg_argv[2] = NULL;
  57. prg_envp[0] = NULL;
  58. execve(prg_argv[0], prg_argv, prg_envp);
  59. }
  60. static void ctl_start(void)
  61. {
  62. char prg_name[PATH_MAX + 11];
  63. pid_t pid;
  64. snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir, "bluetoothd");
  65. printf("Starting %s\n", prg_name);
  66. pid = fork();
  67. if (pid < 0) {
  68. perror("Failed to fork new process");
  69. return;
  70. }
  71. if (pid == 0) {
  72. run_valgrind(prg_name);
  73. /* Fallback to no valgrind if running with valgind failed */
  74. run_bluetoothd(prg_name);
  75. exit(0);
  76. }
  77. printf("New process %d created\n", pid);
  78. daemon_pid = pid;
  79. }
  80. static void snoop_start(void)
  81. {
  82. char prg_name[PATH_MAX + 17];
  83. char *prg_argv[3];
  84. char *prg_envp[1];
  85. pid_t pid;
  86. snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir,
  87. "bluetoothd-snoop");
  88. prg_argv[0] = prg_name;
  89. prg_argv[1] = "/tmp/btsnoop_hci.log";
  90. prg_argv[2] = NULL;
  91. prg_envp[0] = NULL;
  92. printf("Starting %s\n", prg_name);
  93. pid = fork();
  94. if (pid < 0) {
  95. perror("Failed to fork new process");
  96. return;
  97. }
  98. if (pid == 0) {
  99. execve(prg_argv[0], prg_argv, prg_envp);
  100. exit(0);
  101. }
  102. printf("New process %d created\n", pid);
  103. snoop_pid = pid;
  104. }
  105. static void snoop_stop(void)
  106. {
  107. printf("Stoping %s/%s\n", exec_dir, "bluetoothd-snoop");
  108. kill(snoop_pid, SIGTERM);
  109. }
  110. static void system_socket_callback(int fd, uint32_t events, void *user_data)
  111. {
  112. char buf[4096];
  113. ssize_t len;
  114. if (events & (EPOLLERR | EPOLLHUP)) {
  115. mainloop_remove_fd(fd);
  116. return;
  117. }
  118. len = read(fd, buf, sizeof(buf));
  119. if (len < 0)
  120. return;
  121. printf("Received %s\n", buf);
  122. if (!strcmp(buf, "bluetooth.start=daemon")) {
  123. if (daemon_pid > 0)
  124. return;
  125. ctl_start();
  126. } else if (!strcmp(buf, "bluetooth.start=snoop")) {
  127. if (snoop_pid > 0)
  128. return;
  129. snoop_start();
  130. } else if (!strcmp(buf, "bluetooth.stop=snoop")) {
  131. if (snoop_pid > 0)
  132. snoop_stop();
  133. }
  134. }
  135. static void signal_callback(int signum, void *user_data)
  136. {
  137. switch (signum) {
  138. case SIGINT:
  139. case SIGTERM:
  140. mainloop_quit();
  141. break;
  142. case SIGCHLD:
  143. while (1) {
  144. pid_t pid;
  145. int status;
  146. pid = waitpid(WAIT_ANY, &status, WNOHANG);
  147. if (pid < 0 || pid == 0)
  148. break;
  149. printf("Process %d terminated with status=%d\n",
  150. pid, status);
  151. if (pid == daemon_pid)
  152. daemon_pid = -1;
  153. else if (pid == snoop_pid)
  154. snoop_pid = -1;
  155. }
  156. break;
  157. }
  158. }
  159. int main(int argc, char *argv[])
  160. {
  161. const char SYSTEM_SOCKET_PATH[] = "\0android_system";
  162. struct sockaddr_un addr;
  163. int fd;
  164. mainloop_init();
  165. printf("Android system emulator ver %s\n", VERSION);
  166. snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0]));
  167. fd = socket(PF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
  168. if (fd < 0) {
  169. perror("Failed to create system socket");
  170. return EXIT_FAILURE;
  171. }
  172. memset(&addr, 0, sizeof(addr));
  173. addr.sun_family = AF_UNIX;
  174. memcpy(addr.sun_path, SYSTEM_SOCKET_PATH, sizeof(SYSTEM_SOCKET_PATH));
  175. if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  176. perror("Failed to bind system socket");
  177. close(fd);
  178. return EXIT_FAILURE;
  179. }
  180. mainloop_add_fd(fd, EPOLLIN, system_socket_callback, NULL, NULL);
  181. /* Make sure bluetoothd creates files with proper permissions */
  182. umask(0177);
  183. return mainloop_run_with_signal(signal_callback, NULL);
  184. }