File: | build-scan/../src/login/inhibit.c |
Warning: | line 255, column 35 Although the value stored to 'w' is used in the enclosing expression, the value is never actually read from 'w' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
2 | |
3 | #include <fcntl.h> |
4 | #include <getopt.h> |
5 | #include <stdio.h> |
6 | #include <stdlib.h> |
7 | #include <unistd.h> |
8 | |
9 | #include "sd-bus.h" |
10 | |
11 | #include "alloc-util.h" |
12 | #include "bus-error.h" |
13 | #include "bus-util.h" |
14 | #include "fd-util.h" |
15 | #include "format-util.h" |
16 | #include "pager.h" |
17 | #include "process-util.h" |
18 | #include "signal-util.h" |
19 | #include "strv.h" |
20 | #include "user-util.h" |
21 | #include "util.h" |
22 | |
23 | static const char* arg_what = "idle:sleep:shutdown"; |
24 | static const char* arg_who = NULL((void*)0); |
25 | static const char* arg_why = "Unknown reason"; |
26 | static const char* arg_mode = NULL((void*)0); |
27 | static bool_Bool arg_no_pager = false0; |
28 | |
29 | static enum { |
30 | ACTION_INHIBIT, |
31 | ACTION_LIST |
32 | } arg_action = ACTION_INHIBIT; |
33 | |
34 | static int inhibit(sd_bus *bus, sd_bus_error *error) { |
35 | _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *reply = NULL((void*)0); |
36 | int r; |
37 | int fd; |
38 | |
39 | r = sd_bus_call_method( |
40 | bus, |
41 | "org.freedesktop.login1", |
42 | "/org/freedesktop/login1", |
43 | "org.freedesktop.login1.Manager", |
44 | "Inhibit", |
45 | error, |
46 | &reply, |
47 | "ssss", arg_what, arg_who, arg_why, arg_mode); |
48 | if (r < 0) |
49 | return r; |
50 | |
51 | r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_UNIX_FD, &fd); |
52 | if (r < 0) |
53 | return r; |
54 | |
55 | r = fcntl(fd, F_DUPFD_CLOEXEC1030, 3); |
56 | if (r < 0) |
57 | return -errno(*__errno_location ()); |
58 | |
59 | return r; |
60 | } |
61 | |
62 | static int print_inhibitors(sd_bus *bus, sd_bus_error *error) { |
63 | _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *reply = NULL((void*)0); |
64 | const char *what, *who, *why, *mode; |
65 | unsigned int uid, pid; |
66 | unsigned n = 0; |
67 | int r; |
68 | |
69 | (void) pager_open(arg_no_pager, false0); |
70 | |
71 | r = sd_bus_call_method( |
72 | bus, |
73 | "org.freedesktop.login1", |
74 | "/org/freedesktop/login1", |
75 | "org.freedesktop.login1.Manager", |
76 | "ListInhibitors", |
77 | error, |
78 | &reply, |
79 | ""); |
80 | if (r < 0) |
81 | return r; |
82 | |
83 | r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)"); |
84 | if (r < 0) |
85 | return bus_log_parse_error(r); |
86 | |
87 | while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) { |
88 | _cleanup_free___attribute__((cleanup(freep))) char *comm = NULL((void*)0), *u = NULL((void*)0); |
89 | |
90 | if (arg_mode && !streq(mode, arg_mode)(strcmp((mode),(arg_mode)) == 0)) |
91 | continue; |
92 | |
93 | get_process_comm(pid, &comm); |
94 | u = uid_to_name(uid); |
95 | |
96 | printf(" Who: %s (UID "UID_FMT"%" "u""/%s, PID "PID_FMT"%" "i""/%s)\n" |
97 | " What: %s\n" |
98 | " Why: %s\n" |
99 | " Mode: %s\n\n", |
100 | who, uid, strna(u), pid, strna(comm), |
101 | what, |
102 | why, |
103 | mode); |
104 | |
105 | n++; |
106 | } |
107 | if (r < 0) |
108 | return bus_log_parse_error(r); |
109 | |
110 | r = sd_bus_message_exit_container(reply); |
111 | if (r < 0) |
112 | return bus_log_parse_error(r); |
113 | |
114 | printf("%u inhibitors listed.\n", n); |
115 | return 0; |
116 | } |
117 | |
118 | static void help(void) { |
119 | printf("%s [OPTIONS...] {COMMAND} ...\n\n" |
120 | "Execute a process while inhibiting shutdown/sleep/idle.\n\n" |
121 | " -h --help Show this help\n" |
122 | " --version Show package version\n" |
123 | " --no-pager Do not pipe output into a pager\n" |
124 | " --what=WHAT Operations to inhibit, colon separated list of:\n" |
125 | " shutdown, sleep, idle, handle-power-key,\n" |
126 | " handle-suspend-key, handle-hibernate-key,\n" |
127 | " handle-lid-switch\n" |
128 | " --who=STRING A descriptive string who is inhibiting\n" |
129 | " --why=STRING A descriptive string why is being inhibited\n" |
130 | " --mode=MODE One of block or delay\n" |
131 | " --list List active inhibitors\n" |
132 | , program_invocation_short_name); |
133 | } |
134 | |
135 | static int parse_argv(int argc, char *argv[]) { |
136 | |
137 | enum { |
138 | ARG_VERSION = 0x100, |
139 | ARG_WHAT, |
140 | ARG_WHO, |
141 | ARG_WHY, |
142 | ARG_MODE, |
143 | ARG_LIST, |
144 | ARG_NO_PAGER, |
145 | }; |
146 | |
147 | static const struct option options[] = { |
148 | { "help", no_argument0, NULL((void*)0), 'h' }, |
149 | { "version", no_argument0, NULL((void*)0), ARG_VERSION }, |
150 | { "what", required_argument1, NULL((void*)0), ARG_WHAT }, |
151 | { "who", required_argument1, NULL((void*)0), ARG_WHO }, |
152 | { "why", required_argument1, NULL((void*)0), ARG_WHY }, |
153 | { "mode", required_argument1, NULL((void*)0), ARG_MODE }, |
154 | { "list", no_argument0, NULL((void*)0), ARG_LIST }, |
155 | { "no-pager", no_argument0, NULL((void*)0), ARG_NO_PAGER }, |
156 | {} |
157 | }; |
158 | |
159 | int c; |
160 | |
161 | assert(argc >= 0)do { if ((__builtin_expect(!!(!(argc >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("argc >= 0"), "../src/login/inhibit.c" , 161, __PRETTY_FUNCTION__); } while (0); |
162 | assert(argv)do { if ((__builtin_expect(!!(!(argv)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("argv"), "../src/login/inhibit.c", 162, __PRETTY_FUNCTION__ ); } while (0); |
163 | |
164 | while ((c = getopt_long(argc, argv, "+h", options, NULL((void*)0))) >= 0) |
165 | |
166 | switch (c) { |
167 | |
168 | case 'h': |
169 | help(); |
170 | return 0; |
171 | |
172 | case ARG_VERSION: |
173 | return version(); |
174 | |
175 | case ARG_WHAT: |
176 | arg_what = optarg; |
177 | break; |
178 | |
179 | case ARG_WHO: |
180 | arg_who = optarg; |
181 | break; |
182 | |
183 | case ARG_WHY: |
184 | arg_why = optarg; |
185 | break; |
186 | |
187 | case ARG_MODE: |
188 | arg_mode = optarg; |
189 | break; |
190 | |
191 | case ARG_LIST: |
192 | arg_action = ACTION_LIST; |
193 | break; |
194 | |
195 | case ARG_NO_PAGER: |
196 | arg_no_pager = true1; |
197 | break; |
198 | |
199 | case '?': |
200 | return -EINVAL22; |
201 | |
202 | default: |
203 | assert_not_reached("Unhandled option")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, ( "Unhandled option"), "../src/login/inhibit.c", 203, __PRETTY_FUNCTION__ ); } while (0); |
204 | } |
205 | |
206 | if (arg_action == ACTION_INHIBIT && optind == argc) |
207 | arg_action = ACTION_LIST; |
208 | |
209 | else if (arg_action == ACTION_INHIBIT && optind >= argc) { |
210 | log_error("Missing command line to execute.")({ 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/login/inhibit.c", 210, __func__, "Missing command line to execute." ) : -abs(_e); }); |
211 | return -EINVAL22; |
212 | } |
213 | |
214 | return 1; |
215 | } |
216 | |
217 | int main(int argc, char *argv[]) { |
218 | _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0}); |
219 | _cleanup_(sd_bus_flush_close_unrefp)__attribute__((cleanup(sd_bus_flush_close_unrefp))) sd_bus *bus = NULL((void*)0); |
220 | int r; |
221 | |
222 | log_parse_environment()log_parse_environment_realm(LOG_REALM_SYSTEMD); |
223 | log_open(); |
224 | |
225 | r = parse_argv(argc, argv); |
226 | if (r < 0) |
227 | return EXIT_FAILURE1; |
228 | if (r == 0) |
229 | return EXIT_SUCCESS0; |
230 | |
231 | r = sd_bus_default_system(&bus); |
232 | if (r < 0) { |
233 | log_error_errno(r, "Failed to connect to bus: %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/login/inhibit.c", 233, __func__, "Failed to connect to bus: %m" ) : -abs(_e); }); |
234 | return EXIT_FAILURE1; |
235 | } |
236 | |
237 | if (arg_action == ACTION_LIST) { |
238 | |
239 | r = print_inhibitors(bus, &error); |
240 | pager_close(); |
241 | if (r < 0) { |
242 | log_error("Failed to list inhibitors: %s", bus_error_message(&error, -r))({ 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/login/inhibit.c", 242, __func__, "Failed to list inhibitors: %s" , bus_error_message(&error, -r)) : -abs(_e); }); |
243 | return EXIT_FAILURE1; |
244 | } |
245 | |
246 | } else { |
247 | _cleanup_close___attribute__((cleanup(closep))) int fd = -1; |
248 | _cleanup_free___attribute__((cleanup(freep))) char *w = NULL((void*)0); |
249 | pid_t pid; |
250 | |
251 | /* Ignore SIGINT and allow the forked process to receive it */ |
252 | (void) ignore_signals(SIGINT2, -1); |
253 | |
254 | if (!arg_who) |
255 | arg_who = w = strv_join(argv + optind, " "); |
Although the value stored to 'w' is used in the enclosing expression, the value is never actually read from 'w' | |
256 | |
257 | if (!arg_mode) |
258 | arg_mode = "block"; |
259 | |
260 | fd = inhibit(bus, &error); |
261 | if (fd < 0) { |
262 | log_error("Failed to inhibit: %s", bus_error_message(&error, fd))({ 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/login/inhibit.c", 262, __func__, "Failed to inhibit: %s" , bus_error_message(&error, fd)) : -abs(_e); }); |
263 | return EXIT_FAILURE1; |
264 | } |
265 | |
266 | r = safe_fork("(inhibit)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid); |
267 | if (r < 0) |
268 | return EXIT_FAILURE1; |
269 | if (r == 0) { |
270 | /* Child */ |
271 | execvp(argv[optind], argv + optind); |
272 | log_open(); |
273 | log_error_errno(errno, "Failed to execute %s: %m", argv[optind])({ 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/login/inhibit.c", 273, __func__, "Failed to execute %s: %m", argv[optind]) : -abs(_e); }); |
274 | _exit(EXIT_FAILURE1); |
275 | } |
276 | |
277 | r = wait_for_terminate_and_check(argv[optind], pid, WAIT_LOG); |
278 | return r < 0 ? EXIT_FAILURE1 : r; |
279 | } |
280 | |
281 | return EXIT_SUCCESS0; |
282 | } |