|
28 | 28 | #include "startupreason.h"
|
29 | 29 | #include "log_sys.h"
|
30 | 30 |
|
31 |
| -#define MAX_KERNEL_COMMAND_LINE_SIZE 4096 |
32 | 31 | #define CURRENT_KERNEL_CMDLINE "/proc/cmdline"
|
33 | 32 |
|
34 |
| -static int get_cmdline_bootreason(char *bootreason) |
| 33 | +static int get_cmdline_bootreason(char *bootreason, const size_t limit) |
35 | 34 | {
|
36 |
| - int res, len = MAX_KERNEL_COMMAND_LINE_SIZE; |
37 |
| - char *p, *p1, *p2; |
38 |
| - char *cmdline; |
39 |
| - const char key[] = "bootreason="; |
40 |
| - |
41 |
| - cmdline = malloc(len); |
42 |
| - if (!cmdline) { |
43 |
| - LOGE("failed to allocate memory to read %s\n", |
44 |
| - CURRENT_KERNEL_CMDLINE); |
45 |
| - return -1; |
46 |
| - } |
47 |
| - res = file_read_string(CURRENT_KERNEL_CMDLINE, cmdline, len); |
48 |
| - if (res <= 0) { |
| 35 | + int res; |
| 36 | + unsigned long size; |
| 37 | + char *start, *p1, *p2, *end; |
| 38 | + void *cmdline; |
| 39 | + const char key[] = "ABL.reset="; |
| 40 | + |
| 41 | + res = read_file(CURRENT_KERNEL_CMDLINE, &size, &cmdline); |
| 42 | + if (res < 0) { |
49 | 43 | LOGE("failed to read file %s - %s\n",
|
50 | 44 | CURRENT_KERNEL_CMDLINE, strerror(errno));
|
51 |
| - free(cmdline); |
52 | 45 | return -1;
|
53 | 46 | }
|
54 | 47 |
|
55 |
| - p = strstr(cmdline, key); |
56 |
| - if (!p) { |
| 48 | + start = strstr(cmdline, key); |
| 49 | + if (!start) { |
| 50 | + LOGW("can't find reboot reason with key (%s) in cmdline\n", |
| 51 | + key); |
57 | 52 | free(cmdline);
|
58 | 53 | return 0;
|
59 | 54 | }
|
60 |
| - p += strlen(key); |
61 |
| - p1 = strstr(p, " "); |
62 |
| - p2 = strstr(p, "\n"); |
63 |
| - if (p2 && !p1) |
64 |
| - *p2 = '\0'; |
65 |
| - else if (p2 && p2 < p1) |
66 |
| - *p2 = '\0'; |
67 |
| - else if (p1) |
68 |
| - *p1 = '\0'; |
69 |
| - |
70 |
| - strncpy(bootreason, p, strlen(p) + 1); |
| 55 | + |
| 56 | + /* if the string contains ' ' or '\n', break it by '\0' */ |
| 57 | + start += strlen(key); |
| 58 | + p1 = strchr(start, ' '); |
| 59 | + p2 = strchr(start, '\n'); |
| 60 | + if (p2 && p1) |
| 61 | + end = MIN(p1, p2); |
| 62 | + else |
| 63 | + end = MAX(p1, p2); |
| 64 | + |
| 65 | + if (end) |
| 66 | + *end = 0; |
| 67 | + |
| 68 | + const size_t len = MIN(strlen(start), limit - 1); |
| 69 | + |
| 70 | + if (len > 0) |
| 71 | + memcpy(bootreason, start, len + 1); |
| 72 | + |
71 | 73 | free(cmdline);
|
72 |
| - return strlen(bootreason); |
| 74 | + return len; |
73 | 75 | }
|
74 | 76 |
|
75 |
| -static void get_default_bootreason(char *bootreason) |
| 77 | +static int get_default_bootreason(char *bootreason, const size_t limit) |
76 | 78 | {
|
77 |
| - int ret; |
78 |
| - unsigned int i; |
79 |
| - char bootreason_prop[MAX_KERNEL_COMMAND_LINE_SIZE]; |
| 79 | + int len; |
| 80 | + int i; |
80 | 81 |
|
81 |
| - ret = get_cmdline_bootreason(bootreason_prop); |
82 |
| - if (ret <= 0) |
83 |
| - return; |
| 82 | + len = get_cmdline_bootreason(bootreason, limit); |
| 83 | + if (len <= 0) |
| 84 | + return len; |
84 | 85 |
|
85 |
| - for (i = 0; i < strlen(bootreason_prop); i++) |
86 |
| - bootreason[i] = toupper(bootreason_prop[i]); |
87 |
| - bootreason[i] = '\0'; |
| 86 | + for (i = 0; i < len; i++) |
| 87 | + bootreason[i] = toupper(bootreason[i]); |
| 88 | + |
| 89 | + return len; |
88 | 90 |
|
89 | 91 | }
|
90 | 92 |
|
91 |
| -void read_startupreason(char *startupreason) |
| 93 | +void read_startupreason(char *startupreason, const size_t limit) |
92 | 94 | {
|
93 |
| - strcpy(startupreason, "UNKNOWN"); |
94 |
| - get_default_bootreason(startupreason); |
| 95 | + int res; |
| 96 | + static char reboot_reason_cache[REBOOT_REASON_SIZE]; |
| 97 | + |
| 98 | + if (!reboot_reason_cache[0]) { |
| 99 | + /* fill cache */ |
| 100 | + res = get_default_bootreason(reboot_reason_cache, |
| 101 | + sizeof(reboot_reason_cache)); |
| 102 | + if (res <= 0) |
| 103 | + strncpy(reboot_reason_cache, "UNKNOWN", |
| 104 | + sizeof(reboot_reason_cache)); |
| 105 | + } |
| 106 | + |
| 107 | + const size_t len = MIN(strlen(reboot_reason_cache), limit - 1); |
| 108 | + |
| 109 | + memcpy(startupreason, reboot_reason_cache, len); |
| 110 | + *(startupreason + len) = 0; |
| 111 | + return; |
95 | 112 | }
|
0 commit comments