Bug Summary

File:src/usr.sbin/iostat/iostat.c
Warning:line 157, column 2
Value stored to 'argc' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name iostat.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 pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/iostat/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/iostat/../../usr.bin/vmstat -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/iostat/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/iostat/iostat.c
1/* $OpenBSD: iostat.c,v 1.44 2021/07/12 15:09:21 beck Exp $ */
2/* $NetBSD: iostat.c,v 1.10 1996/10/25 18:21:58 scottr Exp $ */
3
4/*
5 * Copyright (c) 1996 John M. Vinopal
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed for the NetBSD Project
19 * by John M. Vinopal.
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36/*-
37 * Copyright (c) 1986, 1991, 1993
38 * The Regents of the University of California. All rights reserved.
39 *
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE.
63 */
64
65#include <sys/limits.h>
66#include <sys/time.h>
67#include <sys/sched.h>
68
69#include <err.h>
70#include <ctype.h>
71#include <signal.h>
72#include <stdio.h>
73#include <stdlib.h>
74#include <string.h>
75#include <unistd.h>
76#include <kvm.h>
77
78#include "dkstats.h"
79
80/* Defined in dkstats.c */
81extern struct _disk cur, last;
82extern int dk_ndrive;
83
84/* Namelist and memory files. */
85kvm_t *kd;
86char *nlistf, *memf;
87
88int hz, reps, interval;
89static int todo = 0;
90
91volatile sig_atomic_t wantheader;
92
93#define ISSET(x, a)((x) & (a)) ((x) & (a))
94#define SHOW_CPU0x0001 0x0001
95#define SHOW_TTY0x0002 0x0002
96#define SHOW_STATS_10x0004 0x0004
97#define SHOW_STATS_20x0008 0x0008
98#define SHOW_TOTALS0x0080 0x0080
99
100static void cpustats(void);
101static void disk_stats(double);
102static void disk_stats2(double);
103static void sigheader(int);
104static void header(void);
105static void usage(void);
106static void display(void);
107static void selectdrives(char **);
108
109void dkswap(void);
110void dkreadstats(void);
111int dkinit(int);
112
113int
114main(int argc, char *argv[])
115{
116 const char *errstr;
117 int ch, hdrcnt;
118 struct timespec ts;
119
120 while ((ch = getopt(argc, argv, "Cc:dDIM:N:Tw:")) != -1)
121 switch(ch) {
122 case 'c':
123 reps = strtonum(optarg, 1, INT_MAX0x7fffffff, &errstr);
124 if (errstr)
125 errx(1, "repetition count is %s", errstr);
126 break;
127 case 'C':
128 todo |= SHOW_CPU0x0001;
129 break;
130 case 'd':
131 todo |= SHOW_STATS_10x0004;
132 break;
133 case 'D':
134 todo |= SHOW_STATS_20x0008;
135 break;
136 case 'I':
137 todo |= SHOW_TOTALS0x0080;
138 break;
139 case 'M':
140 memf = optarg;
141 break;
142 case 'N':
143 nlistf = optarg;
144 break;
145 case 'T':
146 todo |= SHOW_TTY0x0002;
147 break;
148 case 'w':
149 interval = strtonum(optarg, 1, 100000000, &errstr);
150 if (errstr)
151 errx(1, "wait is %s", errstr);
152 break;
153 case '?':
154 default:
155 usage();
156 }
157 argc -= optind;
Value stored to 'argc' is never read
158 argv += optind;
159
160 if (!ISSET(todo, SHOW_CPU | SHOW_TTY | SHOW_STATS_1 | SHOW_STATS_2)((todo) & (0x0001 | 0x0002 | 0x0004 | 0x0008)))
161 todo |= SHOW_CPU0x0001 | SHOW_TTY0x0002 | SHOW_STATS_10x0004;
162
163 dkinit(0);
164
165 if (unveil("/", "") == -1)
166 err(1, "unveil /");
167 if (unveil(NULL((void *)0), NULL((void *)0)) == -1)
168 err(1, "unveil");
169
170 dkreadstats();
171 selectdrives(argv);
172
173 ts.tv_sec = interval;
174 ts.tv_nsec = 0;
175
176 /* print a new header on sigcont */
177 signal(SIGCONT19, sigheader);
178
179 for (hdrcnt = 1;;) {
180 if (!--hdrcnt || wantheader) {
181 header();
182 hdrcnt = 20;
183 wantheader = 0;
184 }
185
186 if (!ISSET(todo, SHOW_TOTALS)((todo) & (0x0080)))
187 dkswap();
188 display();
189
190 if (reps >= 0 && --reps <= 0)
191 break;
192 nanosleep(&ts, NULL((void *)0));
193 dkreadstats();
194 if (last.dk_ndrive != cur.dk_ndrive)
195 wantheader = 1;
196 }
197 exit(0);
198}
199
200/*ARGSUSED*/
201static void
202sigheader(int signo)
203{
204 wantheader = 1;
205}
206
207static void
208header(void)
209{
210 int i;
211 static int printedheader = 0;
212
213 if (printedheader && !isatty(STDOUT_FILENO1))
214 return;
215
216 /* Main Headers. */
217 if (ISSET(todo, SHOW_TTY)((todo) & (0x0002))) {
218 if (ISSET(todo, SHOW_TOTALS)((todo) & (0x0080)))
219 printf(" tty");
220 else
221 printf(" tty");
222 }
223
224 if (ISSET(todo, SHOW_STATS_1)((todo) & (0x0004)))
225 for (i = 0; i < dk_ndrive; i++)
226 if (cur.dk_select[i]) {
227 printf(" %18.18s ", cur.dk_name[i]);
228 }
229 if (ISSET(todo, SHOW_STATS_2)((todo) & (0x0008)))
230 for (i = 0; i < dk_ndrive; i++)
231 if (cur.dk_select[i])
232 printf(" %17.17s ", cur.dk_name[i]);
233
234 if (ISSET(todo, SHOW_CPU)((todo) & (0x0001)))
235 printf(" cpu");
236 printf("\n");
237
238 /* Sub-Headers. */
239 if (ISSET(todo, SHOW_TTY)((todo) & (0x0002))) {
240 if (ISSET(todo, SHOW_TOTALS)((todo) & (0x0080)))
241 printf(" tin tout");
242 else
243 printf(" tin tout");
244 }
245
246 if (ISSET(todo, SHOW_STATS_1)((todo) & (0x0004)))
247 for (i = 0; i < dk_ndrive; i++)
248 if (cur.dk_select[i]) {
249 if (ISSET(todo, SHOW_TOTALS)((todo) & (0x0080)))
250 printf(" KB/t xfr MB ");
251 else
252 printf(" KB/t t/s MB/s ");
253 }
254 if (ISSET(todo, SHOW_STATS_2)((todo) & (0x0008)))
255 for (i = 0; i < dk_ndrive; i++)
256 if (cur.dk_select[i])
257 printf(" KB xfr time ");
258
259 if (ISSET(todo, SHOW_CPU)((todo) & (0x0001)))
260 printf(" us ni sy sp in id");
261 printf("\n");
262}
263
264static void
265disk_stats(double etime)
266{
267 int dn;
268 double atime, mbps;
269
270 for (dn = 0; dn < dk_ndrive; ++dn) {
271 if (!cur.dk_select[dn])
272 continue;
273
274 /* average Kbytes per transfer. */
275 if (cur.dk_rxfer[dn] + cur.dk_wxfer[dn])
276 mbps = ((cur.dk_rbytes[dn] + cur.dk_wbytes[dn]) /
277 (1024.0)) / (cur.dk_rxfer[dn] + cur.dk_wxfer[dn]);
278 else
279 mbps = 0.0;
280
281 printf(" %5.2f", mbps);
282
283 /* average transfers per second. */
284 if (ISSET(todo, SHOW_TOTALS)((todo) & (0x0080)))
285 printf(" %5.0f", (cur.dk_rxfer[dn] + cur.dk_wxfer[dn]) / etime);
286 else
287 printf(" %4.0f", (cur.dk_rxfer[dn] + cur.dk_wxfer[dn]) / etime);
288
289 /* time busy in disk activity */
290 atime = (double)cur.dk_time[dn].tv_sec +
291 ((double)cur.dk_time[dn].tv_usec / (double)1000000);
292
293 /* Megabytes per second. */
294 if (atime != 0.0)
295 mbps = (cur.dk_rbytes[dn] + cur.dk_wbytes[dn]) /
296 (double)(1024 * 1024);
297 else
298 mbps = 0;
299 if (ISSET(todo, SHOW_TOTALS)((todo) & (0x0080)))
300 printf(" %6.2f ", mbps / etime);
301 else
302 printf(" %7.2f ", mbps / etime);
303 }
304}
305
306static void
307disk_stats2(double etime)
308{
309 int dn;
310 double atime;
311
312 for (dn = 0; dn < dk_ndrive; ++dn) {
313 if (!cur.dk_select[dn])
314 continue;
315
316 /* average kbytes per second. */
317 printf(" %7.0f",
318 (cur.dk_rbytes[dn] + cur.dk_wbytes[dn]) / (1024.0) / etime);
319
320 /* average transfers per second. */
321 printf(" %4.0f", (cur.dk_rxfer[dn] + cur.dk_wxfer[dn]) / etime);
322
323 /* average time busy in disk activity. */
324 atime = (double)cur.dk_time[dn].tv_sec +
325 ((double)cur.dk_time[dn].tv_usec / (double)1000000);
326 printf(" %4.2f ", atime / etime);
327 }
328}
329
330static void
331cpustats(void)
332{
333 int state;
334 double t = 0;
335
336 for (state = 0; state < CPUSTATES6; ++state)
337 t += cur.cp_time[state];
338 if (!t)
339 t = 1.0;
340 /* States are generally never 100% and can use %3.0f. */
341 for (state = 0; state < CPUSTATES6; ++state)
342 printf("%3.0f", 100. * cur.cp_time[state] / t);
343}
344
345static void
346usage(void)
347{
348 fprintf(stderr(&__sF[2]),
349"usage: iostat [-CDdIT] [-c count] [-M core] [-N system] [-w wait] [drives]\n");
350 exit(1);
351}
352
353static void
354display(void)
355{
356 int i;
357 double etime;
358
359 /* Sum up the elapsed ticks. */
360 etime = 0.0;
361 for (i = 0; i < CPUSTATES6; i++)
362 etime += cur.cp_time[i];
363 if (etime == 0.0)
364 etime = 1.0;
365 /* Convert to seconds. */
366 etime /= (float)hz;
367
368 /* If we're showing totals only, then don't divide by the
369 * system time.
370 */
371 if (ISSET(todo, SHOW_TOTALS)((todo) & (0x0080)))
372 etime = 1.0;
373
374 if (ISSET(todo, SHOW_TTY)((todo) & (0x0002))) {
375 if (ISSET(todo, SHOW_TOTALS)((todo) & (0x0080)))
376 printf("%6.0f %8.0f", cur.tk_nin / etime,
377 cur.tk_nout / etime);
378 else
379 printf("%4.0f %4.0f", cur.tk_nin / etime,
380 cur.tk_nout / etime);
381 }
382
383 if (ISSET(todo, SHOW_STATS_1)((todo) & (0x0004)))
384 disk_stats(etime);
385
386 if (ISSET(todo, SHOW_STATS_2)((todo) & (0x0008)))
387 disk_stats2(etime);
388
389 if (ISSET(todo, SHOW_CPU)((todo) & (0x0001)))
390 cpustats();
391
392 printf("\n");
393 fflush(stdout(&__sF[1]));
394}
395
396static void
397selectdrives(char *argv[])
398{
399 const char *errstr;
400 int i, ndrives;
401
402 /*
403 * Choose drives to be displayed. Priority goes to (in order) drives
404 * supplied as arguments and default drives. If everything isn't
405 * filled in and there are drives not taken care of, display the first
406 * few that fit.
407 *
408 * The backward compatibility syntax is:
409 * iostat [ drives ] [ interval [ count ] ]
410 */
411 for (ndrives = 0; *argv; ++argv) {
412 if (isdigit((unsigned char)**argv))
413 break;
414 for (i = 0; i < dk_ndrive; i++) {
415 if (strcmp(cur.dk_name[i], *argv))
416 continue;
417 cur.dk_select[i] = 1;
418 ++ndrives;
419 break;
420 }
421 if (i == dk_ndrive)
422 errx(1, "invalid interval or drive name: %s", *argv);
423 }
424 if (*argv) {
425 interval = strtonum(*argv, 1, 100000000, &errstr);
426 if (errstr)
427 errx(1, "interval is %s", errstr);
428 if (*++argv) {
429 reps = strtonum(*argv, 1, INT_MAX0x7fffffff, &errstr);
430 if (errstr)
431 errx(1, "repetition count is %s", errstr);
432 ++argv;
433 }
434 }
435 if (*argv)
436 errx(1, "too many arguments");
437
438 if (interval) {
439 if (!reps)
440 reps = -1;
441 } else
442 if (reps)
443 interval = 1;
444
445 /* Pick up to 4 drives if none specified. */
446 if (ndrives == 0)
447 for (i = 0; i < dk_ndrive && ndrives < 4; i++) {
448 if (cur.dk_select[i])
449 continue;
450 cur.dk_select[i] = 1;
451 ++ndrives;
452 }
453}