Bug Summary

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'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name inhibit.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I systemd-inhibit.p -I . -I .. -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/login/inhibit.c
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
23static const char* arg_what = "idle:sleep:shutdown";
24static const char* arg_who = NULL((void*)0);
25static const char* arg_why = "Unknown reason";
26static const char* arg_mode = NULL((void*)0);
27static bool_Bool arg_no_pager = false0;
28
29static enum {
30 ACTION_INHIBIT,
31 ACTION_LIST
32} arg_action = ACTION_INHIBIT;
33
34static 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
62static 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
118static 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
135static 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
217int 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}