Print this page
10703 smatch unreachable code checking needs reworking
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/ucblib/libdbm/dbm.c
+++ new/usr/src/ucblib/libdbm/dbm.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 -/* All Rights Reserved */
27 +/* All Rights Reserved */
28 28
29 29 /*
30 30 * Portions of this source code were derived from Berkeley 4.3 BSD
31 31 * under license from the Regents of the University of California.
32 32 */
33 33
34 34 /*
35 - * Copyright (c) 2018, Joyent, Inc.
35 + * Copyright 2019 Joyent, Inc.
36 36 */
37 37
38 38 /*LINTLIBRARY*/
39 39
40 40 #include <sys/types.h>
41 41 #include <stdio.h>
42 42 #include <unistd.h>
43 43 #include <stdlib.h>
44 44 #include <strings.h>
45 45 #include <malloc.h>
46 46 #include <sys/stat.h>
47 47 #include <sys/fcntl.h>
48 48 #include <dbm.h>
49 49 #include <errno.h>
50 50
51 51 /* forward declarations */
52 52 /* could be all static if not were for older *.a releases */
53 53 void chkblk(char buf[PBLKSIZ]);
54 54 void delitem(char buf[PBLKSIZ], int n);
55 55 void dbm_access(long hash);
56 56 int getbit(void);
57 57 int setbit(void);
58 58 int additem(char buf[PBLKSIZ], datum item);
59 59 int cmpdatum(datum d1, datum d2);
60 60
61 61 int
62 62 dbminit(char *file)
63 63 {
64 64 struct stat64 statb;
65 65
66 66 dbrdonly = 0;
67 67 if (strlcpy(pagbuf, file, sizeof (pagbuf)) >= sizeof (pagbuf) ||
68 68 strlcat(pagbuf, ".pag", sizeof (pagbuf)) >= sizeof (pagbuf)) {
69 69 /*
70 70 * file.pag does not fit into pagbuf.
71 71 * fails with ENAMETOOLONG.
72 72 */
73 73 errno = ENAMETOOLONG;
74 74 return (-1);
75 75 }
76 76 pagf = open(pagbuf, 2);
77 77 if (pagf < 0) {
78 78 pagf = open(pagbuf, 0);
79 79 dbrdonly = 1;
80 80 }
81 81
82 82 /*
83 83 * We know this won't overflow so it is safe to ignore the
84 84 * return value; we use strl* to prevent false hits in
85 85 * code sweeps.
86 86 */
87 87 (void) strlcpy(pagbuf, file, sizeof (pagbuf));
88 88 (void) strlcat(pagbuf, ".dir", sizeof (pagbuf));
89 89 dirf = open(pagbuf, 2);
90 90 if (dirf < 0) {
91 91 dirf = open(pagbuf, 0);
92 92 dbrdonly = 1;
93 93 }
94 94 if (pagf < 0 || dirf < 0) {
95 95 (void) printf("cannot open database %s\n", file);
96 96 return (-1);
97 97 }
98 98 /* Guards against large inodes */
99 99 (void) fstat64(dirf, &statb);
100 100 maxbno = (off_t)statb.st_size * BYTESIZ - 1;
101 101 return (0);
102 102 }
103 103
104 104 static long oldb1 = -1L;
105 105 static long oldb2 = -1L;
106 106
107 107 /* Avoid using cached data for subsequent accesses. */
108 108 int
109 109 dbmflush(void)
110 110 {
111 111 oldb1 = -1L;
112 112 oldb2 = -1L;
113 113 return (0);
114 114 }
115 115
116 116 /* Clean up after ourself. */
117 117 int
118 118 dbmclose(void)
119 119 {
120 120 (void) close(pagf);
121 121 (void) close(dirf);
122 122 bitno = 0;
123 123 maxbno = 0;
124 124 blkno = 0;
125 125 hmask = 0;
126 126 oldb1 = -1L;
127 127 oldb2 = -1L;
128 128 return (0);
129 129 }
130 130
131 131 long
132 132 forder(datum key)
133 133 {
134 134 long hash;
135 135
136 136 hash = calchash(key);
137 137 for (hmask = 0; ; hmask = (hmask<<1)+1) {
138 138 blkno = hash & hmask;
139 139 bitno = blkno + hmask;
140 140 if (getbit() == 0)
141 141 break;
142 142 }
143 143 return (blkno);
144 144 }
145 145
146 146 datum
147 147 fetch(datum key)
148 148 {
149 149 int i;
150 150 datum item;
151 151
152 152 dbm_access(calchash(key));
153 153 for (i = 0; ; i += 2) {
154 154 item = makdatum(pagbuf, i);
155 155 if (item.dptr == NULL)
156 156 return (item);
157 157 if (cmpdatum(key, item) == 0) {
158 158 item = makdatum(pagbuf, i+1);
159 159 if (item.dptr == NULL)
160 160 (void) printf("items not in pairs\n");
161 161 return (item);
162 162 }
163 163 }
164 164 }
165 165
166 166 int
167 167 delete(datum key)
168 168 {
169 169 int i;
170 170 datum item;
171 171
172 172 if (dbrdonly)
173 173 return (-1);
174 174 dbm_access(calchash(key));
175 175 for (i = 0; ; i += 2) {
176 176 item = makdatum(pagbuf, i);
177 177 if (item.dptr == NULL)
178 178 return (-1);
179 179 if (cmpdatum(key, item) == 0) {
180 180 delitem(pagbuf, i);
181 181 delitem(pagbuf, i);
182 182 break;
183 183 }
184 184 }
185 185 (void) lseek(pagf, blkno*PBLKSIZ, 0);
186 186 (void) write(pagf, pagbuf, PBLKSIZ);
187 187 return (0);
188 188 }
189 189
190 190 int
191 191 store(datum key, datum dat)
192 192 {
193 193 int i;
194 194 datum item;
195 195 char ovfbuf[PBLKSIZ];
196 196 datum Sentry;
197 197 int Oneflag;
198 198
199 199 Sentry.dsize = 0;
200 200 Sentry.dptr = NULL;
201 201
202 202 if (dbrdonly)
203 203 return (-1);
204 204 loop:
205 205 dbm_access(calchash(key));
206 206 for (i = 0; ; i += 2) {
207 207 item = makdatum(pagbuf, i);
208 208 if (item.dptr == NULL)
209 209 break;
210 210 if (cmpdatum(key, item) == 0) {
211 211 delitem(pagbuf, i);
212 212 delitem(pagbuf, i);
213 213 break;
214 214 }
215 215 }
216 216 i = additem(pagbuf, key);
217 217 if (i < 0)
218 218 goto split;
219 219 if (additem(pagbuf, dat) < 0) {
220 220 delitem(pagbuf, i);
221 221 goto split;
222 222 }
223 223 (void) lseek(pagf, blkno*PBLKSIZ, 0);
224 224 (void) write(pagf, pagbuf, PBLKSIZ);
225 225 return (0);
226 226 split:
227 227 if (key.dsize+dat.dsize+3*sizeof (short) >= PBLKSIZ) {
228 228 (void) printf("entry too big\n");
229 229 return (-1);
230 230 }
231 231 bzero(ovfbuf, PBLKSIZ);
232 232 Oneflag = 0;
233 233 for (i = 0; ; ) {
↓ open down ↓ |
188 lines elided |
↑ open up ↑ |
234 234 item = makdatum(pagbuf, i);
235 235 Oneflag++;
236 236 if (item.dptr == NULL) {
237 237 if ((Sentry.dsize == key.dsize) &&
238 238 (strncmp(Sentry.dptr, key.dptr, key.dsize) == 0))
239 239 return (-1);
240 240 if (Oneflag == 2) {
241 241 Sentry.dsize = key.dsize;
242 242 Sentry.dptr = malloc(strlen(key.dptr)+1);
243 243 (void) strncpy(Sentry.dptr, key.dptr,
244 - key.dsize);
244 + key.dsize);
245 245 }
246 246 break;
247 247 }
248 248 if (calchash(item) & (hmask+1)) {
249 249 (void) additem(ovfbuf, item);
250 250 delitem(pagbuf, i);
251 251 item = makdatum(pagbuf, i);
252 252 if (item.dptr == NULL) {
253 253 (void) printf("split not paired\n");
254 254 break;
255 255 }
256 256 (void) additem(ovfbuf, item);
257 257 delitem(pagbuf, i);
258 258 continue;
259 259 }
260 260 i += 2;
261 261 }
262 262 (void) lseek(pagf, blkno*PBLKSIZ, 0);
263 263 if (write(pagf, pagbuf, PBLKSIZ) < 0)
264 264 return (-1);
265 265 (void) lseek(pagf, (blkno+hmask+1)*PBLKSIZ, 0);
266 266 if (write(pagf, ovfbuf, PBLKSIZ) < 0)
267 267 return (-1);
268 268 if (setbit() < 0)
269 269 return (-1);
270 270 goto loop;
271 271 }
272 272
273 273 datum
274 274 firstkey(void)
275 275 {
276 276 return (firsthash(0L));
277 277 }
278 278
279 279 datum
280 280 nextkey(datum key)
281 281 {
282 282 int i;
283 283 datum item, bitem;
284 284 long hash;
285 285 int f;
286 286
287 287 hash = calchash(key);
288 288 dbm_access(hash);
289 289 f = 1;
290 290 for (i = 0; ; i += 2) {
291 291 item = makdatum(pagbuf, i);
292 292 if (item.dptr == NULL)
293 293 break;
294 294 if (cmpdatum(key, item) <= 0)
295 295 continue;
296 296 if (f || cmpdatum(bitem, item) < 0) {
297 297 bitem = item;
298 298 f = 0;
299 299 }
300 300 }
301 301 if (f == 0)
302 302 return (bitem);
303 303 hash = hashinc(hash);
304 304 if (hash == 0)
305 305 return (item);
306 306 return (firsthash(hash));
307 307 }
308 308
309 309 datum
310 310 firsthash(long hash)
311 311 {
312 312 int i;
313 313 datum item, bitem;
314 314
315 315 loop:
316 316 dbm_access(hash);
317 317 bitem = makdatum(pagbuf, 0);
318 318 for (i = 2; ; i += 2) {
319 319 item = makdatum(pagbuf, i);
320 320 if (item.dptr == NULL)
321 321 break;
322 322 if (cmpdatum(bitem, item) < 0)
323 323 bitem = item;
324 324 }
325 325 if (bitem.dptr != NULL)
326 326 return (bitem);
327 327 hash = hashinc(hash);
328 328 if (hash == 0)
329 329 return (item);
330 330 goto loop;
331 331 }
332 332
333 333 void
334 334 dbm_access(long hash)
335 335 {
336 336 ssize_t readsize;
337 337
338 338 for (hmask = 0; ; hmask = (hmask<<1)+1) {
339 339 blkno = hash & hmask;
340 340 bitno = blkno + hmask;
341 341 if (getbit() == 0)
342 342 break;
343 343 }
344 344 if (blkno != oldb1) {
345 345 (void) lseek(pagf, blkno*PBLKSIZ, 0);
346 346 readsize = read(pagf, pagbuf, PBLKSIZ);
347 347 if (readsize != PBLKSIZ) {
348 348 if (readsize < 0) readsize = 0;
349 349 bzero(pagbuf+readsize, PBLKSIZ-readsize);
350 350 }
351 351 chkblk(pagbuf);
352 352 oldb1 = blkno;
353 353 }
354 354 }
355 355
356 356 int
357 357 getbit(void)
358 358 {
359 359 long bn;
360 360 ssize_t readsize;
361 361 long b, i, n;
362 362
363 363 if (bitno > maxbno)
364 364 return (0);
365 365 n = bitno % BYTESIZ;
366 366 bn = bitno / BYTESIZ;
367 367 i = bn % DBLKSIZ;
368 368 b = bn / DBLKSIZ;
369 369 if (b != oldb2) {
370 370 (void) lseek(dirf, (long)b*DBLKSIZ, 0);
371 371 readsize = read(dirf, dirbuf, DBLKSIZ);
372 372 if (readsize != DBLKSIZ) {
373 373 if (readsize < 0) readsize = 0;
374 374 bzero(dirbuf+readsize, DBLKSIZ-readsize);
375 375 }
376 376 oldb2 = b;
377 377 }
378 378 if (dirbuf[i] & (1<<n))
379 379 return (1);
380 380 return (0);
381 381 }
382 382
383 383 int
384 384 setbit(void)
385 385 {
386 386 long bn;
387 387 long i, n, b;
388 388
389 389 if (dbrdonly)
390 390 return (-1);
391 391 if (bitno > maxbno) {
392 392 maxbno = bitno;
393 393 (void) getbit();
394 394 }
395 395 n = bitno % BYTESIZ;
396 396 bn = bitno / BYTESIZ;
397 397 i = bn % DBLKSIZ;
398 398 b = bn / DBLKSIZ;
399 399 dirbuf[i] |= 1<<n;
400 400 (void) lseek(dirf, (long)b*DBLKSIZ, 0);
401 401 if (write(dirf, dirbuf, DBLKSIZ) < 0)
402 402 return (-1);
403 403 return (0);
404 404 }
405 405
406 406 datum
407 407 makdatum(char buf[PBLKSIZ], int n)
408 408 {
409 409 short *sp;
410 410 int t;
411 411 datum item;
412 412
413 413 sp = (short *)buf;
414 414 if (n < 0 || n >= sp[0])
415 415 goto null;
416 416 t = PBLKSIZ;
417 417 if (n > 0)
418 418 t = sp[n+1-1];
419 419 item.dptr = buf+sp[n+1];
420 420 item.dsize = t - sp[n+1];
421 421 return (item);
422 422
423 423 null:
424 424 item.dptr = NULL;
425 425 item.dsize = 0;
426 426 return (item);
427 427 }
428 428
429 429 int
430 430 cmpdatum(datum d1, datum d2)
431 431 {
432 432 int n;
433 433 char *p1, *p2;
434 434
↓ open down ↓ |
180 lines elided |
↑ open up ↑ |
435 435 n = d1.dsize;
436 436 if (n != d2.dsize)
437 437 return (n - d2.dsize);
438 438 if (n == 0)
439 439 return (0);
440 440 p1 = d1.dptr;
441 441 p2 = d2.dptr;
442 442 do
443 443 if (*p1++ != *p2++)
444 444 return (*--p1 - *--p2);
445 - while (--n);
445 + while (--n)
446 + ;
446 447 return (0);
447 448 }
448 449
449 450 int hitab[16]
450 451 /*
451 452 * ken's
452 453 * {
453 454 * 055,043,036,054,063,014,004,005,
454 455 * 010,064,077,000,035,027,025,071,
455 456 * };
456 457 */
457 458 = { 61, 57, 53, 49, 45, 41, 37, 33,
458 459 29, 25, 21, 17, 13, 9, 5, 1,
459 460 };
460 461 long hltab[64] = {
461 462 06100151277L, 06106161736L, 06452611562L, 05001724107L,
462 463 02614772546L, 04120731531L, 04665262210L, 07347467531L,
463 464 06735253126L, 06042345173L, 03072226605L, 01464164730L,
464 465 03247435524L, 07652510057L, 01546775256L, 05714532133L,
465 466 06173260402L, 07517101630L, 02431460343L, 01743245566L,
466 467 00261675137L, 02433103631L, 03421772437L, 04447707466L,
467 468 04435620103L, 03757017115L, 03641531772L, 06767633246L,
468 469 02673230344L, 00260612216L, 04133454451L, 00615531516L,
469 470 06137717526L, 02574116560L, 02304023373L, 07061702261L,
470 471 05153031405L, 05322056705L, 07401116734L, 06552375715L,
471 472 06165233473L, 05311063631L, 01212221723L, 01052267235L,
472 473 06000615237L, 01075222665L, 06330216006L, 04402355630L,
473 474 01451177262L, 02000133436L, 06025467062L, 07121076461L,
474 475 03123433522L, 01010635225L, 01716177066L, 05161746527L,
475 476 01736635071L, 06243505026L, 03637211610L, 01756474365L,
476 477 04723077174L, 03642763134L, 05750130273L, 03655541561L,
477 478 };
478 479
479 480 long
480 481 hashinc(long hash)
481 482 {
482 483 long bit;
483 484
484 485 hash &= hmask;
485 486 bit = hmask+1;
486 487 for (;;) {
487 488 bit >>= 1;
488 489 if (bit == 0)
489 490 return (0L);
490 491 if ((hash&bit) == 0)
491 492 return (hash|bit);
492 493 hash &= ~bit;
493 494 }
494 495 }
495 496
496 497 long
497 498 calchash(datum item)
498 499 {
499 500 int i, j, f;
500 501 long hashl;
501 502 int hashi;
502 503
503 504 hashl = 0;
504 505 hashi = 0;
505 506 for (i = 0; i < item.dsize; i++) {
506 507 f = item.dptr[i];
507 508 for (j = 0; j < BYTESIZ; j += 4) {
508 509 hashi += hitab[f&017];
509 510 hashl += hltab[hashi&63];
510 511 f >>= 4;
511 512 }
512 513 }
513 514 return (hashl);
514 515 }
515 516
516 517 void
517 518 delitem(char buf[PBLKSIZ], int n)
518 519 {
519 520 short *sp;
520 521 int i1, i2, i3;
521 522
522 523 sp = (short *)buf;
523 524 if (n < 0 || n >= sp[0])
524 525 goto bad;
525 526 i1 = sp[n+1];
526 527 i2 = PBLKSIZ;
527 528 if (n > 0)
528 529 i2 = sp[n+1-1];
529 530 i3 = sp[sp[0]+1-1];
530 531 if (i2 > i1)
531 532 while (i1 > i3) {
532 533 i1--;
533 534 i2--;
534 535 buf[i2] = buf[i1];
535 536 buf[i1] = 0;
536 537 }
537 538 i2 -= i1;
538 539 for (i1 = n+1; i1 < sp[0]; i1++)
539 540 sp[i1+1-1] = sp[i1+1] + i2;
540 541 sp[0]--;
541 542 sp[sp[0]+1] = 0;
542 543 return;
543 544
544 545 bad:
545 546 (void) printf("bad delitem\n");
546 547 abort();
547 548 }
548 549
549 550 int
550 551 additem(char buf[PBLKSIZ], datum item)
551 552 {
552 553 short *sp;
553 554 int i1, i2;
554 555
555 556 sp = (short *)buf;
556 557 i1 = PBLKSIZ;
557 558 if (sp[0] > 0)
558 559 i1 = sp[sp[0]+1-1];
559 560 i1 -= item.dsize;
560 561 i2 = (int)((sp[0]+2) * sizeof (short));
561 562 if (i1 <= i2)
562 563 return (-1);
563 564 sp[sp[0]+1] = (short)i1;
564 565 for (i2 = 0; i2 < item.dsize; i2++) {
565 566 buf[i1] = item.dptr[i2];
566 567 i1++;
567 568 }
568 569 sp[0]++;
569 570 return (sp[0]-1);
570 571 }
571 572
572 573 void
573 574 chkblk(char buf[PBLKSIZ])
574 575 {
575 576 short *sp;
576 577 int t, i;
577 578
578 579 sp = (short *)buf;
579 580 t = PBLKSIZ;
580 581 for (i = 0; i < sp[0]; i++) {
581 582 if (sp[i+1] > t)
↓ open down ↓ |
126 lines elided |
↑ open up ↑ |
582 583 goto bad;
583 584 t = sp[i+1];
584 585 }
585 586 if (t < (sp[0]+1)*sizeof (short))
586 587 goto bad;
587 588 return;
588 589
589 590 bad:
590 591 (void) printf("bad block\n");
591 592 abort();
592 - bzero(buf, PBLKSIZ);
593 593 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX