Bug Summary

File:src/bin/ksh/tree.c
Warning:line 274, column 12
Although the value stored to 'c' is used in the enclosing expression, the value is never actually read from 'c'

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 tree.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/bin/ksh/obj -resource-dir /usr/local/lib/clang/13.0.0 -D EMACS -D VI -I . -I /usr/src/bin/ksh -I /usr/src/bin/ksh/../../lib/libc/gen -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/bin/ksh/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/bin/ksh/tree.c
1/* $OpenBSD: tree.c,v 1.34 2018/04/09 17:53:36 tobias Exp $ */
2
3/*
4 * command tree climbing
5 */
6
7#include <string.h>
8
9#include "sh.h"
10
11#define INDENT4 4
12
13#define tputc(c, shf)shf_putchar(c, shf); shf_putchar(c, shf);
14static void ptree(struct op *, int, struct shf *);
15static void pioact(struct shf *, int, struct ioword *);
16static void tputC(int, struct shf *);
17static void tputS(char *, struct shf *);
18static void vfptreef(struct shf *, int, const char *, va_list);
19static struct ioword **iocopy(struct ioword **, Area *);
20static void iofree(struct ioword **, Area *);
21
22/*
23 * print a command tree
24 */
25
26static void
27ptree(struct op *t, int indent, struct shf *shf)
28{
29 char **w;
30 struct ioword **ioact;
31 struct op *t1;
32
33 Chain:
34 if (t == NULL((void*)0))
35 return;
36 switch (t->type) {
37 case TCOM1:
38 if (t->vars)
39 for (w = t->vars; *w != NULL((void*)0); )
40 fptreef(shf, indent, "%S ", *w++);
41 else
42 fptreef(shf, indent, "#no-vars# ");
43 if (t->args)
44 for (w = t->args; *w != NULL((void*)0); )
45 fptreef(shf, indent, "%S ", *w++);
46 else
47 fptreef(shf, indent, "#no-args# ");
48 break;
49 case TEXEC21:
50 t = t->left;
51 goto Chain;
52 case TPAREN2:
53 fptreef(shf, indent + 2, "( %T) ", t->left);
54 break;
55 case TPIPE3:
56 fptreef(shf, indent, "%T| ", t->left);
57 t = t->right;
58 goto Chain;
59 case TLIST4:
60 fptreef(shf, indent, "%T%;", t->left);
61 t = t->right;
62 goto Chain;
63 case TOR5:
64 case TAND6:
65 fptreef(shf, indent, "%T%s %T",
66 t->left, (t->type==TOR5) ? "||" : "&&", t->right);
67 break;
68 case TBANG7:
69 fptreef(shf, indent, "! ");
70 t = t->right;
71 goto Chain;
72 case TDBRACKET8:
73 {
74 int i;
75
76 fptreef(shf, indent, "[[");
77 for (i = 0; t->args[i]; i++)
78 fptreef(shf, indent, " %S", t->args[i]);
79 fptreef(shf, indent, " ]] ");
80 break;
81 }
82 case TSELECT10:
83 fptreef(shf, indent, "select %s ", t->str);
84 /* FALLTHROUGH */
85 case TFOR9:
86 if (t->type == TFOR9)
87 fptreef(shf, indent, "for %s ", t->str);
88 if (t->vars != NULL((void*)0)) {
89 fptreef(shf, indent, "in ");
90 for (w = t->vars; *w; )
91 fptreef(shf, indent, "%S ", *w++);
92 fptreef(shf, indent, "%;");
93 }
94 fptreef(shf, indent + INDENT4, "do%N%T", t->left);
95 fptreef(shf, indent, "%;done ");
96 break;
97 case TCASE11:
98 fptreef(shf, indent, "case %S in", t->str);
99 for (t1 = t->left; t1 != NULL((void*)0); t1 = t1->right) {
100 fptreef(shf, indent, "%N(");
101 for (w = t1->vars; *w != NULL((void*)0); w++)
102 fptreef(shf, indent, "%S%c", *w,
103 (w[1] != NULL((void*)0)) ? '|' : ')');
104 fptreef(shf, indent + INDENT4, "%;%T%N;;", t1->left);
105 }
106 fptreef(shf, indent, "%Nesac ");
107 break;
108 case TIF12:
109 case TELIF15:
110 /* 3 == strlen("if ") */
111 fptreef(shf, indent + 3, "if %T", t->left);
112 for (;;) {
113 t = t->right;
114 if (t->left != NULL((void*)0)) {
115 fptreef(shf, indent, "%;");
116 fptreef(shf, indent + INDENT4, "then%N%T",
117 t->left);
118 }
119 if (t->right == NULL((void*)0) || t->right->type != TELIF15)
120 break;
121 t = t->right;
122 fptreef(shf, indent, "%;");
123 /* 5 == strlen("elif ") */
124 fptreef(shf, indent + 5, "elif %T", t->left);
125 }
126 if (t->right != NULL((void*)0)) {
127 fptreef(shf, indent, "%;");
128 fptreef(shf, indent + INDENT4, "else%;%T", t->right);
129 }
130 fptreef(shf, indent, "%;fi ");
131 break;
132 case TWHILE13:
133 case TUNTIL14:
134 /* 6 == strlen("while"/"until") */
135 fptreef(shf, indent + 6, "%s %T",
136 (t->type==TWHILE13) ? "while" : "until",
137 t->left);
138 fptreef(shf, indent, "%;do");
139 fptreef(shf, indent + INDENT4, "%;%T", t->right);
140 fptreef(shf, indent, "%;done ");
141 break;
142 case TBRACE17:
143 fptreef(shf, indent + INDENT4, "{%;%T", t->left);
144 fptreef(shf, indent, "%;} ");
145 break;
146 case TCOPROC22:
147 fptreef(shf, indent, "%T|& ", t->left);
148 break;
149 case TASYNC18:
150 fptreef(shf, indent, "%T& ", t->left);
151 break;
152 case TFUNCT19:
153 fptreef(shf, indent,
154 t->u.ksh_func ? "function %s %T" : "%s() %T",
155 t->str, t->left);
156 break;
157 case TTIME20:
158 fptreef(shf, indent, "time %T", t->left);
159 break;
160 default:
161 fptreef(shf, indent, "<botch>");
162 break;
163 }
164 if ((ioact = t->ioact) != NULL((void*)0)) {
165 int need_nl = 0;
166
167 while (*ioact != NULL((void*)0))
168 pioact(shf, indent, *ioact++);
169 /* Print here documents after everything else... */
170 for (ioact = t->ioact; *ioact != NULL((void*)0); ) {
171 struct ioword *iop = *ioact++;
172
173 /* heredoc is 0 when tracing (set -x) */
174 if ((iop->flag & IOTYPE0xF) == IOHERE0x4 && iop->heredoc) {
175 tputc('\n', shf)shf_putchar('\n', shf);;
176 shf_puts(iop->heredoc, shf);
177 fptreef(shf, indent, "%s",
178 evalstr(iop->delim, 0));
179 need_nl = 1;
180 }
181 }
182 /* Last delimiter must be followed by a newline (this often
183 * leads to an extra blank line, but its not worth worrying
184 * about)
185 */
186 if (need_nl)
187 tputc('\n', shf)shf_putchar('\n', shf);;
188 }
189}
190
191static void
192pioact(struct shf *shf, int indent, struct ioword *iop)
193{
194 int flag = iop->flag;
195 int type = flag & IOTYPE0xF;
196 int expected;
197
198 expected = (type == IOREAD0x1 || type == IORDWR0x3 || type == IOHERE0x4) ? 0 :
199 (type == IOCAT0x5 || type == IOWRITE0x2) ? 1 :
200 (type == IODUP0x6 && (iop->unit == !(flag & IORDUP(1<<(7))))) ? iop->unit :
201 iop->unit + 1;
202 if (iop->unit != expected)
203 tputc('0' + iop->unit, shf)shf_putchar('0' + iop->unit, shf);;
204
205 switch (type) {
206 case IOREAD0x1:
207 fptreef(shf, indent, "< ");
208 break;
209 case IOHERE0x4:
210 if (flag&IOSKIP(1<<(5)))
211 fptreef(shf, indent, "<<- ");
212 else
213 fptreef(shf, indent, "<< ");
214 break;
215 case IOCAT0x5:
216 fptreef(shf, indent, ">> ");
217 break;
218 case IOWRITE0x2:
219 if (flag&IOCLOB(1<<(6)))
220 fptreef(shf, indent, ">| ");
221 else
222 fptreef(shf, indent, "> ");
223 break;
224 case IORDWR0x3:
225 fptreef(shf, indent, "<> ");
226 break;
227 case IODUP0x6:
228 if (flag & IORDUP(1<<(7)))
229 fptreef(shf, indent, "<&");
230 else
231 fptreef(shf, indent, ">&");
232 break;
233 }
234 /* name/delim are 0 when printing syntax errors */
235 if (type == IOHERE0x4) {
236 if (iop->delim)
237 fptreef(shf, indent, "%S ", iop->delim);
238 } else if (iop->name)
239 fptreef(shf, indent, (iop->flag & IONAMEXP(1<<(8))) ? "%s " : "%S ",
240 iop->name);
241}
242
243
244/*
245 * variants of fputc, fputs for ptreef and snptreef
246 */
247
248static void
249tputC(int c, struct shf *shf)
250{
251 if ((c&0x60) == 0) { /* C0|C1 */
252 tputc((c&0x80) ? '$' : '^', shf)shf_putchar((c&0x80) ? '$' : '^', shf);;
253 tputc(((c&0x7F)|0x40), shf)shf_putchar(((c&0x7F)|0x40), shf);;
254 } else if ((c&0x7F) == 0x7F) { /* DEL */
255 tputc((c&0x80) ? '$' : '^', shf)shf_putchar((c&0x80) ? '$' : '^', shf);;
256 tputc('?', shf)shf_putchar('?', shf);;
257 } else
258 tputc(c, shf)shf_putchar(c, shf);;
259}
260
261static void
262tputS(char *wp, struct shf *shf)
263{
264 int c, quoted=0;
265
266 /* problems:
267 * `...` -> $(...)
268 * 'foo' -> "foo"
269 * could change encoding to:
270 * OQUOTE ["'] ... CQUOTE ["']
271 * COMSUB [(`] ...\0 (handle $ ` \ and maybe " in `...` case)
272 */
273 while (1)
274 switch ((c = *wp++)) {
Although the value stored to 'c' is used in the enclosing expression, the value is never actually read from 'c'
275 case EOS0:
276 return;
277 case CHAR1:
278 tputC(*wp++, shf);
279 break;
280 case QCHAR2:
281 c = *wp++;
282 if (!quoted || (c == '"' || c == '`' || c == '$'))
283 tputc('\\', shf)shf_putchar('\\', shf);;
284 tputC(c, shf);
285 break;
286 case COMSUB3:
287 tputc('$', shf)shf_putchar('$', shf);;
288 tputc('(', shf)shf_putchar('(', shf);;
289 while (*wp != 0)
290 tputC(*wp++, shf);
291 tputc(')', shf)shf_putchar(')', shf);;
292 wp++;
293 break;
294 case EXPRSUB4:
295 tputc('$', shf)shf_putchar('$', shf);;
296 tputc('(', shf)shf_putchar('(', shf);;
297 tputc('(', shf)shf_putchar('(', shf);;
298 while (*wp != 0)
299 tputC(*wp++, shf);
300 tputc(')', shf)shf_putchar(')', shf);;
301 tputc(')', shf)shf_putchar(')', shf);;
302 wp++;
303 break;
304 case OQUOTE5:
305 quoted = 1;
306 tputc('"', shf)shf_putchar('"', shf);;
307 break;
308 case CQUOTE6:
309 quoted = 0;
310 tputc('"', shf)shf_putchar('"', shf);;
311 break;
312 case OSUBST7:
313 tputc('$', shf)shf_putchar('$', shf);;
314 if (*wp++ == '{')
315 tputc('{', shf)shf_putchar('{', shf);;
316 while ((c = *wp++) != 0)
317 tputC(c, shf);
318 break;
319 case CSUBST8:
320 if (*wp++ == '}')
321 tputc('}', shf)shf_putchar('}', shf);;
322 break;
323 case OPAT9:
324 tputc(*wp++, shf)shf_putchar(*wp++, shf);;
325 tputc('(', shf)shf_putchar('(', shf);;
326 break;
327 case SPAT10:
328 tputc('|', shf)shf_putchar('|', shf);;
329 break;
330 case CPAT11:
331 tputc(')', shf)shf_putchar(')', shf);;
332 break;
333 }
334}
335
336void
337fptreef(struct shf *shf, int indent, const char *fmt, ...)
338{
339 va_list va;
340
341 va_start(va, fmt)__builtin_va_start(va, fmt);
342 vfptreef(shf, indent, fmt, va);
343 va_end(va)__builtin_va_end(va);
344}
345
346char *
347snptreef(char *s, int n, const char *fmt, ...)
348{
349 va_list va;
350 struct shf shf;
351
352 shf_sopen(s, n, SHF_WR0x0002 | (s ? 0 : SHF_DYNAMIC0x0040), &shf);
353
354 va_start(va, fmt)__builtin_va_start(va, fmt);
355 vfptreef(&shf, 0, fmt, va);
356 va_end(va)__builtin_va_end(va);
357
358 return shf_sclose(&shf); /* null terminates */
359}
360
361static void
362vfptreef(struct shf *shf, int indent, const char *fmt, va_list va)
363{
364 int c;
365
366 while ((c = *fmt++)) {
367 if (c == '%') {
368 int64_t n;
369 char *p;
370 int neg;
371
372 switch ((c = *fmt++)) {
373 case 'c':
374 tputc(va_arg(va, int), shf)shf_putchar(__builtin_va_arg(va, int), shf);;
375 break;
376 case 'd': /* decimal */
377 n = va_arg(va, int)__builtin_va_arg(va, int);
378 neg = n < 0;
379 p = u64ton(neg ? -n : n, 10);
380 if (neg)
381 *--p = '-';
382 while (*p)
383 tputc(*p++, shf)shf_putchar(*p++, shf);;
384 break;
385 case 's':
386 p = va_arg(va, char *)__builtin_va_arg(va, char *);
387 while (*p)
388 tputc(*p++, shf)shf_putchar(*p++, shf);;
389 break;
390 case 'S': /* word */
391 p = va_arg(va, char *)__builtin_va_arg(va, char *);
392 tputS(p, shf);
393 break;
394 case 'u': /* unsigned decimal */
395 p = u64ton(va_arg(va, unsigned int)__builtin_va_arg(va, unsigned int), 10);
396 while (*p)
397 tputc(*p++, shf)shf_putchar(*p++, shf);;
398 break;
399 case 'T': /* format tree */
400 ptree(va_arg(va, struct op *)__builtin_va_arg(va, struct op *), indent, shf);
401 break;
402 case ';': /* newline or ; */
403 case 'N': /* newline or space */
404 if (shf->flags & SHF_STRING0x0100) {
405 if (c == ';')
406 tputc(';', shf)shf_putchar(';', shf);;
407 tputc(' ', shf)shf_putchar(' ', shf);;
408 } else {
409 int i;
410
411 tputc('\n', shf)shf_putchar('\n', shf);;
412 for (i = indent; i >= 8; i -= 8)
413 tputc('\t', shf)shf_putchar('\t', shf);;
414 for (; i > 0; --i)
415 tputc(' ', shf)shf_putchar(' ', shf);;
416 }
417 break;
418 case 'R':
419 pioact(shf, indent, va_arg(va, struct ioword *)__builtin_va_arg(va, struct ioword *));
420 break;
421 default:
422 tputc(c, shf)shf_putchar(c, shf);;
423 break;
424 }
425 } else
426 tputc(c, shf)shf_putchar(c, shf);;
427 }
428}
429
430/*
431 * copy tree (for function definition)
432 */
433
434struct op *
435tcopy(struct op *t, Area *ap)
436{
437 struct op *r;
438 char **tw, **rw;
439
440 if (t == NULL((void*)0))
441 return NULL((void*)0);
442
443 r = alloc(sizeof(struct op), ap);
444
445 r->type = t->type;
446 r->u.evalflags = t->u.evalflags;
447
448 r->str = t->type == TCASE11 ? wdcopy(t->str, ap) : str_save(t->str, ap);
449
450 if (t->vars == NULL((void*)0))
451 r->vars = NULL((void*)0);
452 else {
453 for (tw = t->vars; *tw++ != NULL((void*)0); )
454 ;
455 rw = r->vars = areallocarray(NULL((void*)0), tw - t->vars + 1,
456 sizeof(*tw), ap);
457 for (tw = t->vars; *tw != NULL((void*)0); )
458 *rw++ = wdcopy(*tw++, ap);
459 *rw = NULL((void*)0);
460 }
461
462 if (t->args == NULL((void*)0))
463 r->args = NULL((void*)0);
464 else {
465 for (tw = t->args; *tw++ != NULL((void*)0); )
466 ;
467 rw = r->args = areallocarray(NULL((void*)0), tw - t->args + 1,
468 sizeof(*tw), ap);
469 for (tw = t->args; *tw != NULL((void*)0); )
470 *rw++ = wdcopy(*tw++, ap);
471 *rw = NULL((void*)0);
472 }
473
474 r->ioact = (t->ioact == NULL((void*)0)) ? NULL((void*)0) : iocopy(t->ioact, ap);
475
476 r->left = tcopy(t->left, ap);
477 r->right = tcopy(t->right, ap);
478 r->lineno = t->lineno;
479
480 return r;
481}
482
483char *
484wdcopy(const char *wp, Area *ap)
485{
486 size_t len = wdscan(wp, EOS0) - wp;
487 return memcpy(alloc(len, ap), wp, len);
488}
489
490/* return the position of prefix c in wp plus 1 */
491char *
492wdscan(const char *wp, int c)
493{
494 int nest = 0;
495
496 while (1)
497 switch (*wp++) {
498 case EOS0:
499 return (char *) wp;
500 case CHAR1:
501 case QCHAR2:
502 wp++;
503 break;
504 case COMSUB3:
505 case EXPRSUB4:
506 while (*wp++ != 0)
507 ;
508 break;
509 case OQUOTE5:
510 case CQUOTE6:
511 break;
512 case OSUBST7:
513 nest++;
514 while (*wp++ != '\0')
515 ;
516 break;
517 case CSUBST8:
518 wp++;
519 if (c == CSUBST8 && nest == 0)
520 return (char *) wp;
521 nest--;
522 break;
523 case OPAT9:
524 nest++;
525 wp++;
526 break;
527 case SPAT10:
528 case CPAT11:
529 if (c == wp[-1] && nest == 0)
530 return (char *) wp;
531 if (wp[-1] == CPAT11)
532 nest--;
533 break;
534 default:
535 internal_warningf(
536 "%s: unknown char 0x%x (carrying on)",
537 __func__, wp[-1]);
538 }
539}
540
541/* return a copy of wp without any of the mark up characters and
542 * with quote characters (" ' \) stripped.
543 * (string is allocated from ATEMP)
544 */
545char *
546wdstrip(const char *wp)
547{
548 struct shf shf;
549 int c;
550
551 shf_sopen(NULL((void*)0), 32, SHF_WR0x0002 | SHF_DYNAMIC0x0040, &shf);
552
553 /* problems:
554 * `...` -> $(...)
555 * x${foo:-"hi"} -> x${foo:-hi}
556 * x${foo:-'hi'} -> x${foo:-hi}
557 */
558 while (1)
559 switch ((c = *wp++)) {
560 case EOS0:
561 return shf_sclose(&shf); /* null terminates */
562 case CHAR1:
563 case QCHAR2:
564 shf_putchar(*wp++, &shf);
565 break;
566 case COMSUB3:
567 shf_putchar('$', &shf);
568 shf_putchar('(', &shf);
569 while (*wp != 0)
570 shf_putchar(*wp++, &shf);
571 shf_putchar(')', &shf);
572 break;
573 case EXPRSUB4:
574 shf_putchar('$', &shf);
575 shf_putchar('(', &shf);
576 shf_putchar('(', &shf);
577 while (*wp != 0)
578 shf_putchar(*wp++, &shf);
579 shf_putchar(')', &shf);
580 shf_putchar(')', &shf);
581 break;
582 case OQUOTE5:
583 break;
584 case CQUOTE6:
585 break;
586 case OSUBST7:
587 shf_putchar('$', &shf);
588 if (*wp++ == '{')
589 shf_putchar('{', &shf);
590 while ((c = *wp++) != 0)
591 shf_putchar(c, &shf);
592 break;
593 case CSUBST8:
594 if (*wp++ == '}')
595 shf_putchar('}', &shf);
596 break;
597 case OPAT9:
598 shf_putchar(*wp++, &shf);
599 shf_putchar('(', &shf);
600 break;
601 case SPAT10:
602 shf_putchar('|', &shf);
603 break;
604 case CPAT11:
605 shf_putchar(')', &shf);
606 break;
607 }
608}
609
610static struct ioword **
611iocopy(struct ioword **iow, Area *ap)
612{
613 struct ioword **ior;
614 int i;
615
616 for (ior = iow; *ior++ != NULL((void*)0); )
617 ;
618 ior = areallocarray(NULL((void*)0), ior - iow + 1, sizeof(*ior), ap);
619
620 for (i = 0; iow[i] != NULL((void*)0); i++) {
621 struct ioword *p, *q;
622
623 p = iow[i];
624 q = alloc(sizeof(*p), ap);
625 ior[i] = q;
626 *q = *p;
627 if (p->name != NULL((void*)0))
628 q->name = wdcopy(p->name, ap);
629 if (p->delim != NULL((void*)0))
630 q->delim = wdcopy(p->delim, ap);
631 if (p->heredoc != NULL((void*)0))
632 q->heredoc = str_save(p->heredoc, ap);
633 }
634 ior[i] = NULL((void*)0);
635
636 return ior;
637}
638
639/*
640 * free tree (for function definition)
641 */
642
643void
644tfree(struct op *t, Area *ap)
645{
646 char **w;
647
648 if (t == NULL((void*)0))
649 return;
650
651 afree(t->str, ap);
652
653 if (t->vars != NULL((void*)0)) {
654 for (w = t->vars; *w != NULL((void*)0); w++)
655 afree(*w, ap);
656 afree(t->vars, ap);
657 }
658
659 if (t->args != NULL((void*)0)) {
660 for (w = t->args; *w != NULL((void*)0); w++)
661 afree(*w, ap);
662 afree(t->args, ap);
663 }
664
665 if (t->ioact != NULL((void*)0))
666 iofree(t->ioact, ap);
667
668 tfree(t->left, ap);
669 tfree(t->right, ap);
670
671 afree(t, ap);
672}
673
674static void
675iofree(struct ioword **iow, Area *ap)
676{
677 struct ioword **iop;
678 struct ioword *p;
679
680 for (iop = iow; (p = *iop++) != NULL((void*)0); ) {
681 afree(p->name, ap);
682 afree(p->delim, ap);
683 afree(p->heredoc, ap);
684 afree(p, ap);
685 }
686 afree(iow, ap);
687}