Bug Summary

File:src/usr.bin/systat/swap.c
Warning:line 219, column 39
Division by zero

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 swap.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.bin/systat/obj -resource-dir /usr/local/lib/clang/13.0.0 -D NOKVM -I /usr/src/usr.bin/systat/../../usr.bin/vmstat -I /usr/src/usr.bin/systat/../../sbin/pfctl -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/systat/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.bin/systat/swap.c
1/* $OpenBSD: swap.c,v 1.28 2019/06/28 13:35:04 deraadt Exp $ */
2/* $NetBSD: swap.c,v 1.9 1998/12/26 07:05:08 marc Exp $ */
3
4/*-
5 * Copyright (c) 1997 Matthew R. Green. All rights reserved.
6 * Copyright (c) 1980, 1992, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include <sys/types.h>
35#include <sys/signal.h>
36#include <sys/conf.h>
37#include <sys/ioctl.h>
38#include <sys/stat.h>
39#include <sys/swap.h>
40
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44#include <errno(*__errno()).h>
45#include <unistd.h>
46
47#include "systat.h"
48
49
50static long blocksize;
51static int hlen, nswap, rnswap;
52static struct swapent *swap_devices;
53
54void print_sw(void);
55int read_sw(void);
56int select_sw(void);
57static void showswap(int i);
58static void showtotal(void);
59
60
61field_def fields_sw[] = {
62 {"DISK", 6, 16, 1, FLD_ALIGN_LEFT0, -1, 0, 0, 0},
63 {"BLOCKS", 5, 10, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0},
64 {"USED", 5, 10, 1, FLD_ALIGN_RIGHT1, -1, 0, 0, 0},
65 {"", 40, 80, 1, FLD_ALIGN_BAR4, -1, 0, 0, 100},
66};
67
68#define FLD_SW_NAME(&fields_sw[0]) FIELD_ADDR(fields_sw,0)(&fields_sw[0])
69#define FLD_SW_BLOCKS(&fields_sw[1]) FIELD_ADDR(fields_sw,1)(&fields_sw[1])
70#define FLD_SW_USED(&fields_sw[2]) FIELD_ADDR(fields_sw,2)(&fields_sw[2])
71#define FLD_SW_BAR(&fields_sw[3]) FIELD_ADDR(fields_sw,3)(&fields_sw[3])
72
73/* Define views */
74field_def *view_sw_0[] = {
75 FLD_SW_NAME(&fields_sw[0]), FLD_SW_BLOCKS(&fields_sw[1]), FLD_SW_USED(&fields_sw[2]), FLD_SW_BAR(&fields_sw[3]), NULL((void *)0)
76};
77
78
79/* Define view managers */
80struct view_manager swap_mgr = {
81 "Swap", select_sw, read_sw, NULL((void *)0), print_header,
82 print_sw, keyboard_callback, NULL((void *)0), NULL((void *)0)
83};
84
85field_view views_sw[] = {
86 {view_sw_0, "swap", '6', &swap_mgr},
87 {NULL((void *)0), NULL((void *)0), 0, NULL((void *)0)}
88};
89
90
91int
92select_sw(void)
93{
94 if (swap_devices == NULL((void *)0) || nswap == 0)
95 num_disp = 1;
96 else
97 num_disp = nswap;
98 if (nswap > 1)
99 num_disp++;
100 return (0);
101}
102
103int
104read_sw(void)
105{
106 num_disp = 1;
107
108 nswap = swapctl(SWAP_NSWAP3, 0, 0);
109
110 if (nswap < 0)
111 error("error: %s", strerror(errno(*__errno())));
112 if (nswap == 0)
113 return 0;
114
115 if (swap_devices)
116 (void)free(swap_devices);
117
118 swap_devices = calloc(nswap, sizeof(*swap_devices));
119 if (swap_devices == NULL((void *)0))
120 return 0;
121
122 rnswap = swapctl(SWAP_STATS4, (void *)swap_devices, nswap);
123 if (rnswap == -1 || nswap != rnswap)
124 return 0;
125
126 num_disp = nswap;
127 if (nswap > 1)
128 num_disp++;
129
130 return 0;
131}
132
133
134void
135print_sw(void)
136{
137 int n, count = 0;
138
139 if (swap_devices == NULL((void *)0) || nswap == 0) {
1
Assuming 'swap_devices' is not equal to NULL
2
Assuming 'nswap' is not equal to 0
3
Taking false branch
140 print_fld_str(FLD_SW_BAR(&fields_sw[3]), "No swap devices");
141 return;
142 }
143
144
145 for (n = dispstart; n < num_disp; n++) {
4
Assuming 'n' is < 'num_disp'
5
Loop condition is true. Entering loop body
146 if (n >= nswap)
6
Assuming 'n' is >= 'nswap'
7
Taking true branch
147 showtotal();
8
Calling 'showtotal'
148 else
149 showswap(n);
150 count++;
151 if (maxprint > 0 && count >= maxprint)
152 break;
153 }
154
155}
156
157int
158initswap(void)
159{
160 field_view *v;
161
162 char *bs = getbsize(&hlen, &blocksize);
163
164 FLD_SW_BLOCKS(&fields_sw[1])->title = strdup(bs);
165
166 for (v = views_sw; v->name != NULL((void *)0); v++)
167 add_view(v);
168
169 return(1);
170}
171
172
173static void
174showswap(int i)
175{
176 int d, used, xsize;
177 struct swapent *sep;
178 char *p;
179
180 d = blocksize / 512;
181
182 sep = &swap_devices[i];
183
184 p = strrchr(sep->se_path, '/');
185 p = p ? p+1 : sep->se_path;
186
187 print_fld_str(FLD_SW_NAME(&fields_sw[0]), p);
188
189 xsize = sep->se_nblks;
190 used = sep->se_inuse;
191
192 print_fld_uint(FLD_SW_BLOCKS(&fields_sw[1]), xsize / d);
193 print_fld_uint(FLD_SW_USED(&fields_sw[2]), used / d);
194 print_fld_bar(FLD_SW_BAR(&fields_sw[3]), 100 * used / xsize);
195
196 end_line();
197}
198
199static void
200showtotal(void)
201{
202 struct swapent *sep;
203 int d, i, avail, used, xsize, mfree;
204
205 d = blocksize / 512;
206 mfree = avail = 0;
9
The value 0 is assigned to 'avail'
207
208 for (sep = swap_devices, i = 0; i < nswap; i++, sep++) {
10
Assuming 'i' is >= 'nswap'
11
Loop condition is false. Execution continues on line 214
209 xsize = sep->se_nblks;
210 used = sep->se_inuse;
211 avail += xsize;
212 mfree += xsize - used;
213 }
214 used = avail - mfree;
215
216 print_fld_str(FLD_SW_NAME(&fields_sw[0]), "Total");
217 print_fld_uint(FLD_SW_BLOCKS(&fields_sw[1]), avail / d);
218 print_fld_uint(FLD_SW_USED(&fields_sw[2]), used / d);
219 print_fld_bar(FLD_SW_BAR(&fields_sw[3]), 100 * used / avail);
12
Division by zero
220
221 end_line();
222}