logwrapper.c 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Copyright (C) 2008 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <errno.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <sys/wait.h>
  20. #include <unistd.h>
  21. #include <cutils/klog.h>
  22. #include <log/log.h>
  23. #include <logwrap/logwrap.h>
  24. void fatal(const char *msg) {
  25. fprintf(stderr, "%s", msg);
  26. ALOG(LOG_ERROR, "logwrapper", "%s", msg);
  27. exit(-1);
  28. }
  29. void usage() {
  30. fatal(
  31. "Usage: logwrapper [-a] [-d] [-k] BINARY [ARGS ...]\n"
  32. "\n"
  33. "Forks and executes BINARY ARGS, redirecting stdout and stderr to\n"
  34. "the Android logging system. Tag is set to BINARY, priority is\n"
  35. "always LOG_INFO.\n"
  36. "\n"
  37. "-a: Causes logwrapper to do abbreviated logging.\n"
  38. " This logs up to the first 4K and last 4K of the command\n"
  39. " being run, and logs the output when the command exits\n"
  40. "-d: Causes logwrapper to SIGSEGV when BINARY terminates\n"
  41. " fault address is set to the status of wait()\n"
  42. "-k: Causes logwrapper to log to the kernel log instead of\n"
  43. " the Android system log\n");
  44. }
  45. int main(int argc, char* argv[]) {
  46. int seg_fault_on_exit = 0;
  47. int log_target = LOG_ALOG;
  48. bool abbreviated = false;
  49. int ch;
  50. int status = 0xAAAA;
  51. int rc;
  52. while ((ch = getopt(argc, argv, "adk")) != -1) {
  53. switch (ch) {
  54. case 'a':
  55. abbreviated = true;
  56. break;
  57. case 'd':
  58. seg_fault_on_exit = 1;
  59. break;
  60. case 'k':
  61. log_target = LOG_KLOG;
  62. klog_set_level(6);
  63. break;
  64. case '?':
  65. default:
  66. usage();
  67. }
  68. }
  69. argc -= optind;
  70. argv += optind;
  71. if (argc < 1) {
  72. usage();
  73. }
  74. rc = android_fork_execvp_ext(argc, &argv[0], &status, true,
  75. log_target, abbreviated, NULL, NULL, 0);
  76. if (!rc) {
  77. if (WIFEXITED(status))
  78. rc = WEXITSTATUS(status);
  79. else
  80. rc = -ECHILD;
  81. }
  82. if (seg_fault_on_exit) {
  83. uintptr_t fault_address = (uintptr_t) status;
  84. *(int *) fault_address = 0; // causes SIGSEGV with fault_address = status
  85. }
  86. return rc;
  87. }