File: | build-scan/../src/sleep/sleep.c |
Warning: | line 346, column 13 Null pointer passed to 1st parameter expecting 'nonnull' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
2 | /*** | |||
3 | Copyright © 2010-2017 Canonical | |||
4 | Copyright © 2018 Dell Inc. | |||
5 | ***/ | |||
6 | ||||
7 | #include <errno(*__errno_location ()).h> | |||
8 | #include <getopt.h> | |||
9 | #include <linux1/fiemap.h> | |||
10 | #include <stdio.h> | |||
11 | ||||
12 | #include "sd-messages.h" | |||
13 | ||||
14 | #include "parse-util.h" | |||
15 | #include "def.h" | |||
16 | #include "exec-util.h" | |||
17 | #include "fd-util.h" | |||
18 | #include "fileio.h" | |||
19 | #include "log.h" | |||
20 | #include "sleep-config.h" | |||
21 | #include "stdio-util.h" | |||
22 | #include "string-util.h" | |||
23 | #include "strv.h" | |||
24 | #include "util.h" | |||
25 | ||||
26 | static char* arg_verb = NULL((void*)0); | |||
27 | ||||
28 | static int write_hibernate_location_info(void) { | |||
29 | _cleanup_free___attribute__((cleanup(freep))) char *device = NULL((void*)0), *type = NULL((void*)0); | |||
30 | _cleanup_free___attribute__((cleanup(freep))) struct fiemap *fiemap = NULL((void*)0); | |||
31 | char offset_str[DECIMAL_STR_MAX(uint64_t)(2+(sizeof(uint64_t) <= 1 ? 3 : sizeof(uint64_t) <= 2 ? 5 : sizeof(uint64_t) <= 4 ? 10 : sizeof(uint64_t) <= 8 ? 20 : sizeof(int[-2*(sizeof(uint64_t) > 8)])))]; | |||
32 | char device_str[DECIMAL_STR_MAX(uint64_t)(2+(sizeof(uint64_t) <= 1 ? 3 : sizeof(uint64_t) <= 2 ? 5 : sizeof(uint64_t) <= 4 ? 10 : sizeof(uint64_t) <= 8 ? 20 : sizeof(int[-2*(sizeof(uint64_t) > 8)])))]; | |||
33 | _cleanup_close___attribute__((cleanup(closep))) int fd = -1; | |||
34 | struct stat stb; | |||
35 | uint64_t offset; | |||
36 | int r; | |||
37 | ||||
38 | r = find_hibernate_location(&device, &type, NULL((void*)0), NULL((void*)0)); | |||
39 | if (r < 0) | |||
40 | return log_debug_errno(r, "Unable to find hibernation location: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 40, __func__, "Unable to find hibernation location: %m" ) : -abs(_e); }); | |||
41 | ||||
42 | /* if it's a swap partition, we just write the disk to /sys/power/resume */ | |||
43 | if (streq(type, "partition")(strcmp((type),("partition")) == 0)) | |||
44 | return write_string_file("/sys/power/resume", device, 0); | |||
45 | else if (!streq(type, "file")(strcmp((type),("file")) == 0)) | |||
46 | return log_debug_errno(EINVAL, "Invalid hibernate type %s: %m",({ int _level = ((7)), _e = ((22)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 47, __func__, "Invalid hibernate type %s: %m" , type) : -abs(_e); }) | |||
47 | type)({ int _level = ((7)), _e = ((22)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 47, __func__, "Invalid hibernate type %s: %m" , type) : -abs(_e); }); | |||
48 | ||||
49 | /* Only available in 4.17+ */ | |||
50 | if (access("/sys/power/resume_offset", F_OK0) < 0) { | |||
51 | if (errno(*__errno_location ()) == ENOENT2) | |||
52 | return 0; | |||
53 | return log_debug_errno(errno, "/sys/power/resume_offset unavailable: %m")({ int _level = ((7)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/sleep/sleep.c", 53, __func__, "/sys/power/resume_offset unavailable: %m" ) : -abs(_e); }); | |||
54 | } | |||
55 | ||||
56 | r = access("/sys/power/resume_offset", W_OK2); | |||
57 | if (r < 0) | |||
58 | return log_debug_errno(errno, "/sys/power/resume_offset not writeable: %m")({ int _level = ((7)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/sleep/sleep.c", 58, __func__, "/sys/power/resume_offset not writeable: %m" ) : -abs(_e); }); | |||
59 | ||||
60 | fd = open(device, O_RDONLY00 | O_CLOEXEC02000000 | O_NONBLOCK04000); | |||
61 | if (fd < 0) | |||
62 | return log_debug_errno(errno, "Unable to open '%s': %m", device)({ int _level = ((7)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/sleep/sleep.c", 62, __func__, "Unable to open '%s': %m" , device) : -abs(_e); }); | |||
63 | r = fstat(fd, &stb); | |||
64 | if (r < 0) | |||
65 | return log_debug_errno(errno, "Unable to stat %s: %m", device)({ int _level = ((7)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/sleep/sleep.c", 65, __func__, "Unable to stat %s: %m" , device) : -abs(_e); }); | |||
66 | r = read_fiemap(fd, &fiemap); | |||
67 | if (r < 0) | |||
68 | return log_debug_errno(r, "Unable to read extent map for '%s': %m",({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 69, __func__, "Unable to read extent map for '%s': %m" , device) : -abs(_e); }) | |||
69 | device)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 69, __func__, "Unable to read extent map for '%s': %m" , device) : -abs(_e); }); | |||
70 | if (fiemap->fm_mapped_extents == 0) { | |||
71 | log_debug("No extents found in '%s'", device)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 71, __func__, "No extents found in '%s'" , device) : -abs(_e); }); | |||
72 | return -EINVAL22; | |||
73 | } | |||
74 | offset = fiemap->fm_extents[0].fe_physical / page_size(); | |||
75 | xsprintf(offset_str, "%" PRIu64, offset)do { if ((__builtin_expect(!!(!(((size_t) snprintf(offset_str , __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(offset_str), typeof(&*(offset_str))), sizeof(offset_str )/sizeof((offset_str)[0]), ((void)0))), "%" "l" "u", offset) < (__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(offset_str), typeof(&*(offset_str))), sizeof(offset_str )/sizeof((offset_str)[0]), ((void)0))))))),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("xsprintf: " "offset_str" "[] must be big enough" ), "../src/sleep/sleep.c", 75, __PRETTY_FUNCTION__); } while ( 0); | |||
76 | r = write_string_file("/sys/power/resume_offset", offset_str, 0); | |||
77 | if (r < 0) | |||
78 | return log_debug_errno(r, "Failed to write offset '%s': %m",({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 79, __func__, "Failed to write offset '%s': %m" , offset_str) : -abs(_e); }) | |||
79 | offset_str)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 79, __func__, "Failed to write offset '%s': %m" , offset_str) : -abs(_e); }); | |||
80 | ||||
81 | xsprintf(device_str, "%lx", (unsigned long)stb.st_dev)do { if ((__builtin_expect(!!(!(((size_t) snprintf(device_str , __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(device_str), typeof(&*(device_str))), sizeof(device_str )/sizeof((device_str)[0]), ((void)0))), "%lx", (unsigned long )stb.st_dev) < (__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(device_str), typeof(&*(device_str))), sizeof(device_str )/sizeof((device_str)[0]), ((void)0))))))),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("xsprintf: " "device_str" "[] must be big enough" ), "../src/sleep/sleep.c", 81, __PRETTY_FUNCTION__); } while ( 0); | |||
82 | r = write_string_file("/sys/power/resume", device_str, 0); | |||
83 | if (r < 0) | |||
84 | return log_debug_errno(r, "Failed to write device '%s': %m",({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 85, __func__, "Failed to write device '%s': %m" , device_str) : -abs(_e); }) | |||
85 | device_str)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 85, __func__, "Failed to write device '%s': %m" , device_str) : -abs(_e); }); | |||
86 | return 0; | |||
87 | } | |||
88 | ||||
89 | static int write_mode(char **modes) { | |||
90 | int r = 0; | |||
91 | char **mode; | |||
92 | ||||
93 | STRV_FOREACH(mode, modes)for ((mode) = (modes); (mode) && *(mode); (mode)++) { | |||
94 | int k; | |||
95 | ||||
96 | k = write_string_file("/sys/power/disk", *mode, 0); | |||
97 | if (k == 0) | |||
98 | return 0; | |||
99 | ||||
100 | log_debug_errno(k, "Failed to write '%s' to /sys/power/disk: %m",({ int _level = ((7)), _e = ((k)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 101, __func__, "Failed to write '%s' to /sys/power/disk: %m" , *mode) : -abs(_e); }) | |||
101 | *mode)({ int _level = ((7)), _e = ((k)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 101, __func__, "Failed to write '%s' to /sys/power/disk: %m" , *mode) : -abs(_e); }); | |||
102 | if (r == 0) | |||
103 | r = k; | |||
104 | } | |||
105 | ||||
106 | return r; | |||
107 | } | |||
108 | ||||
109 | static int write_state(FILE **f, char **states) { | |||
110 | char **state; | |||
111 | int r = 0; | |||
112 | ||||
113 | STRV_FOREACH(state, states)for ((state) = (states); (state) && *(state); (state) ++) { | |||
114 | int k; | |||
115 | ||||
116 | k = write_string_stream(*f, *state, 0); | |||
117 | if (k == 0) | |||
118 | return 0; | |||
119 | log_debug_errno(k, "Failed to write '%s' to /sys/power/state: %m",({ int _level = ((7)), _e = ((k)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 120, __func__, "Failed to write '%s' to /sys/power/state: %m" , *state) : -abs(_e); }) | |||
120 | *state)({ int _level = ((7)), _e = ((k)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 120, __func__, "Failed to write '%s' to /sys/power/state: %m" , *state) : -abs(_e); }); | |||
121 | if (r == 0) | |||
122 | r = k; | |||
123 | ||||
124 | fclose(*f); | |||
125 | *f = fopen("/sys/power/state", "we"); | |||
126 | if (!*f) | |||
127 | return -errno(*__errno_location ()); | |||
128 | } | |||
129 | ||||
130 | return r; | |||
131 | } | |||
132 | ||||
133 | static int execute(char **modes, char **states) { | |||
134 | ||||
135 | char *arguments[] = { | |||
136 | NULL((void*)0), | |||
137 | (char*) "pre", | |||
138 | arg_verb, | |||
139 | NULL((void*)0) | |||
140 | }; | |||
141 | static const char* const dirs[] = { | |||
142 | SYSTEM_SLEEP_PATH"/usr/lib/systemd/system-sleep", | |||
143 | NULL((void*)0) | |||
144 | }; | |||
145 | ||||
146 | int r; | |||
147 | _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0); | |||
148 | ||||
149 | /* This file is opened first, so that if we hit an error, | |||
150 | * we can abort before modifying any state. */ | |||
151 | f = fopen("/sys/power/state", "we"); | |||
152 | if (!f) | |||
153 | return log_error_errno(errno, "Failed to open /sys/power/state: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/sleep/sleep.c", 153, __func__, "Failed to open /sys/power/state: %m" ) : -abs(_e); }); | |||
154 | ||||
155 | /* Configure the hibernation mode */ | |||
156 | if (!strv_isempty(modes)) { | |||
157 | r = write_hibernate_location_info(); | |||
158 | if (r < 0) | |||
159 | return log_error_errno(r, "Failed to write hibernation disk offset: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 159, __func__, "Failed to write hibernation disk offset: %m" ) : -abs(_e); }); | |||
160 | r = write_mode(modes); | |||
161 | if (r < 0) | |||
162 | return log_error_errno(r, "Failed to write mode to /sys/power/disk: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 162, __func__, "Failed to write mode to /sys/power/disk: %m" ) : -abs(_e); });; | |||
163 | } | |||
164 | ||||
165 | execute_directories(dirs, DEFAULT_TIMEOUT_USEC(90*((usec_t) 1000000ULL)), NULL((void*)0), NULL((void*)0), arguments); | |||
166 | ||||
167 | log_struct(LOG_INFO,log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0 , "../src/sleep/sleep.c", 170, __func__, "MESSAGE_ID=" "6b" "bd" "95" "ee" "97" "79" "41" "e4" "97" "c4" "8b" "e2" "7c" "25" "41" "28", "MESSAGE=" "Suspending system...", "SLEEP=%s", arg_verb , ((void*)0)) | |||
168 | "MESSAGE_ID=" SD_MESSAGE_SLEEP_START_STR,log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0 , "../src/sleep/sleep.c", 170, __func__, "MESSAGE_ID=" "6b" "bd" "95" "ee" "97" "79" "41" "e4" "97" "c4" "8b" "e2" "7c" "25" "41" "28", "MESSAGE=" "Suspending system...", "SLEEP=%s", arg_verb , ((void*)0)) | |||
169 | LOG_MESSAGE("Suspending system..."),log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0 , "../src/sleep/sleep.c", 170, __func__, "MESSAGE_ID=" "6b" "bd" "95" "ee" "97" "79" "41" "e4" "97" "c4" "8b" "e2" "7c" "25" "41" "28", "MESSAGE=" "Suspending system...", "SLEEP=%s", arg_verb , ((void*)0)) | |||
170 | "SLEEP=%s", arg_verb)log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0 , "../src/sleep/sleep.c", 170, __func__, "MESSAGE_ID=" "6b" "bd" "95" "ee" "97" "79" "41" "e4" "97" "c4" "8b" "e2" "7c" "25" "41" "28", "MESSAGE=" "Suspending system...", "SLEEP=%s", arg_verb , ((void*)0)); | |||
171 | ||||
172 | r = write_state(&f, states); | |||
173 | if (r < 0) | |||
174 | return log_error_errno(r, "Failed to write /sys/power/state: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 174, __func__, "Failed to write /sys/power/state: %m" ) : -abs(_e); }); | |||
175 | ||||
176 | log_struct(LOG_INFO,log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0 , "../src/sleep/sleep.c", 179, __func__, "MESSAGE_ID=" "88" "11" "e6" "df" "2a" "8e" "40" "f5" "8a" "94" "ce" "a2" "6f" "8e" "bf" "14", "MESSAGE=" "System resumed.", "SLEEP=%s", arg_verb, (( void*)0)) | |||
177 | "MESSAGE_ID=" SD_MESSAGE_SLEEP_STOP_STR,log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0 , "../src/sleep/sleep.c", 179, __func__, "MESSAGE_ID=" "88" "11" "e6" "df" "2a" "8e" "40" "f5" "8a" "94" "ce" "a2" "6f" "8e" "bf" "14", "MESSAGE=" "System resumed.", "SLEEP=%s", arg_verb, (( void*)0)) | |||
178 | LOG_MESSAGE("System resumed."),log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0 , "../src/sleep/sleep.c", 179, __func__, "MESSAGE_ID=" "88" "11" "e6" "df" "2a" "8e" "40" "f5" "8a" "94" "ce" "a2" "6f" "8e" "bf" "14", "MESSAGE=" "System resumed.", "SLEEP=%s", arg_verb, (( void*)0)) | |||
179 | "SLEEP=%s", arg_verb)log_struct_internal(((LOG_REALM_SYSTEMD) << 10 | (6)), 0 , "../src/sleep/sleep.c", 179, __func__, "MESSAGE_ID=" "88" "11" "e6" "df" "2a" "8e" "40" "f5" "8a" "94" "ce" "a2" "6f" "8e" "bf" "14", "MESSAGE=" "System resumed.", "SLEEP=%s", arg_verb, (( void*)0)); | |||
180 | ||||
181 | arguments[1] = (char*) "post"; | |||
182 | execute_directories(dirs, DEFAULT_TIMEOUT_USEC(90*((usec_t) 1000000ULL)), NULL((void*)0), NULL((void*)0), arguments); | |||
183 | ||||
184 | return r; | |||
185 | } | |||
186 | ||||
187 | static int read_wakealarm(uint64_t *result) { | |||
188 | _cleanup_free___attribute__((cleanup(freep))) char *t = NULL((void*)0); | |||
189 | ||||
190 | if (read_one_line_file("/sys/class/rtc/rtc0/since_epoch", &t) >= 0) | |||
191 | return safe_atou64(t, result); | |||
192 | return -EBADF9; | |||
193 | } | |||
194 | ||||
195 | static int write_wakealarm(const char *str) { | |||
196 | ||||
197 | _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0); | |||
198 | int r; | |||
199 | ||||
200 | f = fopen("/sys/class/rtc/rtc0/wakealarm", "we"); | |||
201 | if (!f) | |||
202 | return log_error_errno(errno, "Failed to open /sys/class/rtc/rtc0/wakealarm: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/sleep/sleep.c", 202, __func__, "Failed to open /sys/class/rtc/rtc0/wakealarm: %m" ) : -abs(_e); }); | |||
203 | ||||
204 | r = write_string_stream(f, str, 0); | |||
205 | if (r < 0) | |||
206 | return log_error_errno(r, "Failed to write '%s' to /sys/class/rtc/rtc0/wakealarm: %m", str)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 206, __func__, "Failed to write '%s' to /sys/class/rtc/rtc0/wakealarm: %m" , str) : -abs(_e); }); | |||
207 | ||||
208 | return 0; | |||
209 | } | |||
210 | ||||
211 | static int execute_s2h(usec_t hibernate_delay_sec) { | |||
212 | ||||
213 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **hibernate_modes = NULL((void*)0), **hibernate_states = NULL((void*)0), | |||
214 | **suspend_modes = NULL((void*)0), **suspend_states = NULL((void*)0); | |||
215 | usec_t orig_time, cmp_time; | |||
216 | char time_str[DECIMAL_STR_MAX(uint64_t)(2+(sizeof(uint64_t) <= 1 ? 3 : sizeof(uint64_t) <= 2 ? 5 : sizeof(uint64_t) <= 4 ? 10 : sizeof(uint64_t) <= 8 ? 20 : sizeof(int[-2*(sizeof(uint64_t) > 8)])))]; | |||
217 | int r; | |||
218 | ||||
219 | r = parse_sleep_config("suspend", &suspend_modes, &suspend_states, | |||
220 | NULL((void*)0)); | |||
221 | if (r < 0) | |||
222 | return r; | |||
223 | ||||
224 | r = parse_sleep_config("hibernate", &hibernate_modes, | |||
225 | &hibernate_states, NULL((void*)0)); | |||
226 | if (r < 0) | |||
227 | return r; | |||
228 | ||||
229 | r = read_wakealarm(&orig_time); | |||
230 | if (r < 0) | |||
231 | return log_error_errno(errno, "Failed to read time: %d", r)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/sleep/sleep.c", 231, __func__, "Failed to read time: %d" , r) : -abs(_e); }); | |||
232 | ||||
233 | orig_time += hibernate_delay_sec / USEC_PER_SEC((usec_t) 1000000ULL); | |||
234 | xsprintf(time_str, "%" PRIu64, orig_time)do { if ((__builtin_expect(!!(!(((size_t) snprintf(time_str, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (time_str), typeof(&*(time_str))), sizeof(time_str)/sizeof ((time_str)[0]), ((void)0))), "%" "l" "u", orig_time) < (__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (time_str), typeof(&*(time_str))), sizeof(time_str)/sizeof ((time_str)[0]), ((void)0))))))),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("xsprintf: " "time_str" "[] must be big enough" ), "../src/sleep/sleep.c", 234, __PRETTY_FUNCTION__); } while (0); | |||
235 | ||||
236 | r = write_wakealarm(time_str); | |||
237 | if (r < 0) | |||
238 | return r; | |||
239 | ||||
240 | log_debug("Set RTC wake alarm for %s", time_str)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 240, __func__, "Set RTC wake alarm for %s" , time_str) : -abs(_e); }); | |||
241 | ||||
242 | r = execute(suspend_modes, suspend_states); | |||
243 | if (r < 0) | |||
244 | return r; | |||
245 | ||||
246 | r = read_wakealarm(&cmp_time); | |||
247 | if (r < 0) | |||
248 | return log_error_errno(errno, "Failed to read time: %d", r)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/sleep/sleep.c", 248, __func__, "Failed to read time: %d" , r) : -abs(_e); }); | |||
249 | ||||
250 | /* reset RTC */ | |||
251 | r = write_wakealarm("0"); | |||
252 | if (r < 0) | |||
253 | return r; | |||
254 | ||||
255 | log_debug("Woke up at %"PRIu64, cmp_time)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 255, __func__, "Woke up at %""l" "u" , cmp_time) : -abs(_e); }); | |||
256 | ||||
257 | /* if woken up after alarm time, hibernate */ | |||
258 | if (cmp_time >= orig_time) | |||
259 | r = execute(hibernate_modes, hibernate_states); | |||
260 | ||||
261 | return r; | |||
262 | } | |||
263 | ||||
264 | static void help(void) { | |||
265 | printf("%s COMMAND\n\n" | |||
266 | "Suspend the system, hibernate the system, or both.\n\n" | |||
267 | "Commands:\n" | |||
268 | " -h --help Show this help and exit\n" | |||
269 | " --version Print version string and exit\n" | |||
270 | " suspend Suspend the system\n" | |||
271 | " hibernate Hibernate the system\n" | |||
272 | " hybrid-sleep Both hibernate and suspend the system\n" | |||
273 | " suspend-then-hibernate Initially suspend and then hibernate\n" | |||
274 | " the system after a fixed period of time\n" | |||
275 | , program_invocation_short_name); | |||
276 | } | |||
277 | ||||
278 | static int parse_argv(int argc, char *argv[]) { | |||
279 | enum { | |||
280 | ARG_VERSION = 0x100, | |||
281 | }; | |||
282 | ||||
283 | static const struct option options[] = { | |||
284 | { "help", no_argument0, NULL((void*)0), 'h' }, | |||
285 | { "version", no_argument0, NULL((void*)0), ARG_VERSION }, | |||
286 | {} | |||
287 | }; | |||
288 | ||||
289 | int c; | |||
290 | ||||
291 | assert(argc >= 0)do { if ((__builtin_expect(!!(!(argc >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("argc >= 0"), "../src/sleep/sleep.c", 291, __PRETTY_FUNCTION__); } while (0); | |||
292 | assert(argv)do { if ((__builtin_expect(!!(!(argv)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("argv"), "../src/sleep/sleep.c", 292, __PRETTY_FUNCTION__ ); } while (0); | |||
293 | ||||
294 | while ((c = getopt_long(argc, argv, "h", options, NULL((void*)0))) >= 0) | |||
295 | switch(c) { | |||
296 | case 'h': | |||
297 | help(); | |||
298 | return 0; /* done */ | |||
299 | ||||
300 | case ARG_VERSION: | |||
301 | return version(); | |||
302 | ||||
303 | case '?': | |||
304 | return -EINVAL22; | |||
305 | ||||
306 | default: | |||
307 | assert_not_reached("Unhandled option")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, ( "Unhandled option"), "../src/sleep/sleep.c", 307, __PRETTY_FUNCTION__ ); } while (0); | |||
308 | } | |||
309 | ||||
310 | if (argc - optind != 1) { | |||
311 | log_error("Usage: %s COMMAND",({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 312, __func__, "Usage: %s COMMAND", program_invocation_short_name) : -abs(_e); }) | |||
312 | program_invocation_short_name)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 312, __func__, "Usage: %s COMMAND", program_invocation_short_name) : -abs(_e); }); | |||
313 | return -EINVAL22; | |||
314 | } | |||
315 | ||||
316 | arg_verb = argv[optind]; | |||
317 | ||||
318 | if (!streq(arg_verb, "suspend")(strcmp((arg_verb),("suspend")) == 0) && | |||
319 | !streq(arg_verb, "hibernate")(strcmp((arg_verb),("hibernate")) == 0) && | |||
320 | !streq(arg_verb, "hybrid-sleep")(strcmp((arg_verb),("hybrid-sleep")) == 0) && | |||
321 | !streq(arg_verb, "suspend-then-hibernate")(strcmp((arg_verb),("suspend-then-hibernate")) == 0)) { | |||
322 | log_error("Unknown command '%s'.", arg_verb)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/sleep/sleep.c", 322, __func__, "Unknown command '%s'." , arg_verb) : -abs(_e); }); | |||
323 | return -EINVAL22; | |||
324 | } | |||
325 | ||||
326 | return 1 /* work to do */; | |||
327 | } | |||
328 | ||||
329 | int main(int argc, char *argv[]) { | |||
330 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **modes = NULL((void*)0), **states = NULL((void*)0); | |||
331 | usec_t delay = 0; | |||
332 | int r; | |||
333 | ||||
334 | log_set_target(LOG_TARGET_AUTO); | |||
335 | log_parse_environment()log_parse_environment_realm(LOG_REALM_SYSTEMD); | |||
336 | log_open(); | |||
337 | ||||
338 | r = parse_argv(argc, argv); | |||
339 | if (r <= 0) | |||
| ||||
340 | goto finish; | |||
341 | ||||
342 | r = parse_sleep_config(arg_verb, &modes, &states, &delay); | |||
343 | if (r < 0) | |||
344 | goto finish; | |||
345 | ||||
346 | if (streq(arg_verb, "suspend-then-hibernate")(strcmp((arg_verb),("suspend-then-hibernate")) == 0)) | |||
| ||||
347 | r = execute_s2h(delay); | |||
348 | else | |||
349 | r = execute(modes, states); | |||
350 | finish: | |||
351 | return r < 0 ? EXIT_FAILURE1 : EXIT_SUCCESS0; | |||
352 | } |