| 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 | } |