source: trunk/minix/commands/elle/sberr.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 17.6 KB
RevLine 
[9]1/* SB - Copyright 1982 by Ken Harrenstien, SRI International
2 * This software is quasi-public; it may be used freely with
3 * like software, but may NOT be sold or made part of licensed
4 * products without permission of the author. In all cases
5 * the source code and any modifications thereto must remain
6 * available to any user.
7 *
8 * This is part of the SB library package.
9 * Any software using the SB library must likewise be made
10 * quasi-public, with freely available sources.
11 */
12
13#define PRINT /* Include printout stuff */
14
15#include "sb.h"
16#include <stdio.h>
17
18extern struct smblk *sbm_nfl;
19extern struct smblk *sbm_list;
20extern struct sdblk *sbx_nfl;
21
22#ifdef PRINT
23#define PRF(stmt) {if(p) stmt;}
24#define PRFBUG(str,stmt) {if(p) stmt;else return(str);}
25#define PRFBAD(str,stmt) {if(p) stmt; return(str);}
26#else
27#define PRF(stmt) ;
28#define PRFBUG(str,stmt) return(str);
29#define PRFBAD(str,stmt) return(str);
30#endif
31
32#ifndef NPTRS
33#define NPTRS (1000) /* Catch loops of period less than this. */
34#endif
35
36int sbe_dec = 0; /* Set nonzero to use decimal printout */
37
38struct ptab {
39 int pt_pflag; /* Printflag value */
40 char *pt_err; /* Error string return */
41 int pt_xerr; /* Error index return */
42 int pt_hidx; /* Highest freelist entry */
43 int pt_nsto; /* # entries stored in table */
44 int pt_cnt; /* # of entry store attempts */
45 struct smblk *pt_tab[NPTRS];
46};
47
48_PROTOTYPE( char *sbe_sdtab, (struct ptab *pt, int p, int phys) );
49_PROTOTYPE( char *sbe_schk, (struct sdblk *sd, struct ptab *pt) );
50_PROTOTYPE( int sbe_tbent, (struct ptab *pt, struct smblk *sm) );
51
52#define PTF_PRF 01 /* Do printout stuff */
53#define PTF_OVFERR 02 /* Complain if table overflows */
54#define PTF_SDPHYS 04 /* Follow SD phys links (else logical links) */
55
56struct flgt {
57 int flg_bit;
58 int flg_chr;
59};
60
61_PROTOTYPE( char *sbe_fstr, (int flags, struct flgt *fp) );
62
63char *sbe_mvfy(), *sbe_mfl(), *sbe_mlst(); /* SBM */
64char *sbe_sbvfy(), *sbe_sbs(); /* SBBUF */
65char *sbe_svfy(), *sbe_sdlist(), *sbe_sdtab(), *sbe_schk(); /* SD */
66char *sbe_fstr(); /* Misc utility */
67
68
69
70/* SBE_MEM() - Print out memory usage list
71*/
72sbe_mem()
73{
74 printf("\nMemory Usage:\n");
75 printf("\tsbm_nfl : %6o\n",sbm_nfl);
76 printf("\tsbm_list: %6o\n",sbm_list);
77 printf("\tsmblk nodes are %o bytes long.\n",sizeof (struct smblk));
78
79 sbe_mlst(1); /* Scan mem list, printing stuff. */
80}
81
82/* SBE_MVFY() - Verify memory allocation structures
83 * Returns error message (0 if no errors found).
84 */
85char *
86sbe_mvfy()
87{ register char *res;
88
89 if((res = sbe_mfl(0))
90 || (res = sbe_mlst(0)))
91 return(res);
92 return(0);
93}
94
95
96/* SBM Debugging Routines */
97
98struct flgt smflgtab[] = {
99 SM_USE, 'U',
100 SM_NXM, 'N',
101 SM_EXT, 'E',
102 SM_MNODS,'M',
103 SM_DNODS,'D',
104 0,0
105};
106
107static char smfhelp[] = "U-Used, N-NXM, E-External, M-SMnodes, D-SDnodes";
108static char smhdline[] = "\
109 SM: back smaddr smlen smuse smflags";
110
111/* SBE_MFL(printflag) - Verify/Print memory freelist
112 * Returns error message (0 if no errors found).
113 */
114char *
115sbe_mfl(p)
116int p;
117{ register struct smblk *sm;
118 register int i;
119 struct ptab smtab; /* For loop detection */
120
121 PRF(printf("Tracing SM node freelist --\n"))
122 PRF(printf(" Maximum loop detection size is %d.", NPTRS))
123 if((sm = sbm_nfl) == 0)
124 { PRF(printf("\n\tNo list.\n"))
125 return(0); /* Null freelist is ok */
126 }
127 smtab.pt_pflag = p ? PTF_PRF : 0;
128 smtab.pt_nsto = smtab.pt_cnt = 0;
129 i = 0; /* Print 8 addrs/line */
130 for(; sm; sm = sm->smforw)
131 {
132 PRF(printf("%s%7o->", (i==0 ? "\n " : ""), sm))
133 if(++i >= 8) i = 0;
134 if(sbe_tbent(&smtab, sm) < 0) /* If hit loop, stop */
135 PRFBAD("SM freelist loop",
136 printf("\nLOOP - %o seen as node %d!!\n",
137 sm, smtab.pt_xerr))
138 if(sm->smflags)
139 { PRF((i = 0, printf("\nFreelist node has flags:\n")))
140 PRFBUG("Free SM flagged", sbe_smp(sm, 0))
141 }
142 }
143 PRF(printf("\nEnd - %d nodes on SM freelist.\n", smtab.pt_cnt))
144 return(0);
145}
146
147/* SBE_MLST(printflag) - Verify/Print allocated memory list.
148 * Returns error message (0 if no errors found).
149 */
150char *
151sbe_mlst(p)
152int p;
153{ register struct smblk *sm, *smf, *smb;
154 char *nextaddr;
155 int i;
156 struct ptab smtab; /* For loop detection */
157
158 PRF(printf("Tracing mem list -- \n"))
159 if((sm = sbm_list) == 0)
160 { PRF(printf("\tNo list?!\n"))
161 if(sbm_nfl) /* Ensure rest are 0 too */
162 return("No mem list?!!");
163 return(0);
164 }
165
166 smtab.pt_pflag = p;
167 smtab.pt_cnt = smtab.pt_nsto = 0;
168 smb = 0;
169 PRF(printf(" Flags: %s\n%s\n", smfhelp, smhdline))
170 for(; sm; sm = smf)
171 { PRF(printf(" %6o: ",sm))
172 if(sbe_tbent(&smtab, sm) < 0)
173 PRFBAD("Loop in mem list!!",
174 printf("LOOP - seen as node %d!!\n", smtab.pt_xerr))
175
176 if(sm->smback == smb)
177 PRF(printf("^ ")) /* Back ptr OK */
178
179 else PRFBUG("Bad back ptr!",
180 printf("%6o BAD Backptr!!\n\t ",sm->smback))
181
182 if((sm->smflags&0377)!= SM_NID)
183 PRFBUG("SM: bad node ID",
184 printf("BAD - no node ID!\n\t "))
185 PRF(printf((sm->smflags&SM_USE) ? " " : "FREE "))
186 if(sm->smlen == 0)
187 PRFBUG("SM: len 0",
188 printf("Zero-length area!"))
189 if((sm->smflags&SM_USE)==0
190 && rndrem(sm->smaddr - sbm_lowaddr))
191 PRFBUG("Bad free-mem block",
192 printf("Bad free-mem block"))
193 PRF(sbe_smp(sm, 1)) /* Print out rest of info */
194
195 if(nextaddr != sm->smaddr
196 && smtab.pt_cnt != 1) /* 1st time needs init */
197 { PRFBUG("Alignment error!",
198 printf("\t BAD!! %6o expected; ",nextaddr))
199#if !(MINIX)
200 PRF((i = sm->smaddr - nextaddr) > 0
201 ? printf("%d skipped.\n",i)
202 : printf("%d overlapped.\n",-i))
203#endif
204 }
205 nextaddr = sm->smaddr + sm->smlen;
206 smf = sm->smforw;
207 smb = sm; /* Save ptr to back */
208 }
209 PRF(printf("End = %6o\n",nextaddr))
210 return(0);
211}
212
213#ifdef PRINT
214sbe_smp(sm,type)
215register struct smblk *sm;
216int type;
217{
218 if(type==0)
219 printf(" %6o: %s ", sm,
220 ((sm->smflags&SM_USE) ? " " : "FREE"));
221 printf("%6o: ", sm->smaddr);
222 printf((sbe_dec ? "%5d. %5d." : "%6o %6o"), sm->smlen, sm->smuse);
223 printf(" %7o = %s\n", sm->smflags, sbe_fstr(sm->smflags, smflgtab));
224}
225#endif /*PRINT*/
226
227
228/* SD (SBSTR) debugging routines */
229
230struct flgt sdflgtab[] = {
231 SD_LOCK, 'L',
232 SD_LCK2, 'T',
233 SD_MOD, '*',
234 0,0
235};
236
237static char sdfhelp[] = "\
238<f> flags: *-MOD (disk outofdate), L-LOCK, T-LCK2 (temp)";
239static char sdhdline[] = "\
240<f> SD: slforw slback sdflgs sdforw sdback sdmem sdfile sdaddr sdlen";
241
242
243/* SBE_SFL(printflag) - Verify/Print SD freelist
244 * Returns error message (0 if no errors found).
245 */
246char *
247sbe_sfl(p)
248int p;
249{ register struct sdblk *sd;
250 register int i;
251 struct ptab sdtab; /* For loop detection */
252
253 PRF(printf("Tracing SDBLK node freelist --\n"))
254 PRF(printf(" Maximum loop detection size is %d.", NPTRS))
255 if((sd = sbx_nfl) == 0)
256 { PRF(printf("\n\tNo list.\n"))
257 return(0); /* Null freelist is ok */
258 }
259 sdtab.pt_pflag = p ? PTF_PRF : 0;
260 sdtab.pt_nsto = sdtab.pt_cnt = 0;
261 i = 0; /* Print 8 addrs/line */
262 for(; sd; sd = sd->slforw)
263 {
264 PRF(printf("%s%7o->", (i==0 ? "\n " : ""), sd))
265 if(++i >= 8) i = 0;
266 if(sbe_tbent(&sdtab, sd) < 0) /* If hit loop, stop */
267 PRFBAD("SD freelist loop",
268 printf("\nLOOP - %o seen as node %d!!",
269 sd, sdtab.pt_xerr))
270 if(sd->sdflags)
271 { PRF((i = 0, printf("\nFreelist node has flags:\n")))
272 PRFBUG("Free SD flagged", sbe_psd(sd))
273 }
274 }
275 PRF(printf("\nEnd - %d nodes on SD freelist.\n", sdtab.pt_cnt))
276 return(0);
277}
278
279
280
281/* SBE_SDS() - Print out all sdblk data stuff
282 */
283sbe_sds()
284{ int sbe_psd();
285
286 printf("Printout of all in-use SDBLKs:\n");
287 printf(" %s\n", sdfhelp);
288 printf("%s\n", sdhdline);
289 sbm_nfor(SM_DNODS,sizeof(struct sdblk),sbe_psd,0);
290 printf("\n");
291}
292
293/* SBE_PSD - Auxiliary for invocation by SBE_SDS above. */
294sbe_psd(sd)
295register struct sdblk *sd;
296{ register int flags;
297
298 flags = sd->sdflags;
299 printf("%c%c%c",
300 ((flags&SD_MOD) ? '*' : ' '),
301 ((flags&SD_LOCK) ? 'L' : ' '),
302 ((flags&SD_LCK2) ? 'T' : ' '));
303
304 printf(" %7o: %6o %6o %6o %6o %6o %6o %6o %7lo %5ld.\n", sd,
305 sd->slforw, sd->slback, sd->sdflags,
306 sd->sdforw, sd->sdback, sd->sdmem,
307 sd->sdfile, sd->sdaddr, sd->sdlen);
308 return(0);
309}
310
311/* SBE_SVFY() - Verify all SD blocks
312 * Returns error message (0 if no errors found).
313 */
314char *
315sbe_svfy()
316{ register char *res;
317 return((res = sbe_sdlist(0,0)) ? res : sbe_sdlist(0,1));
318}
319
320/* SBE_SDLIST(printflag, physflag) - Verify/Print all SD blocks.
321 * Show logical lists if physflag 0
322 * Show physical lists otherwise
323 * Returns error message (0 if no errors found).
324 */
325char *
326sbe_sdlist(p,phys)
327int p, phys;
328{ register char *res;
329 struct ptab sdtab; /* The SDLIST table to use */
330
331 /* First put freelist in table, then scan for all
332 * SD nodes. Each active node (not in table) gets
333 * its entire list traced forward/backward and added to table.
334 */
335 if(res = sbe_sdtab(&sdtab, p, phys)) /* Set up freelist table */
336 return(res);
337
338 /* Freelist entered in table, now scan all SD's */
339 res = (char *)sbm_nfor(SM_DNODS,sizeof(struct sdblk),
340 sbe_schk, &sdtab);
341
342 PRF(printf("\n"))
343 return(res);
344}
345
346/* SBE_SDTAB(tableptr, printflag, physflag) - Auxiliary for SBE_SDLIST.
347 * Stuffs all freelist SDBLK addresses in table for dup detection.
348 * Returns error message (0 if no errors found).
349 */
350char *
351sbe_sdtab(pt, p, phys)
352register struct ptab *pt;
353int p, phys;
354{ register struct sdblk *sd;
355 register int res;
356
357 pt->pt_pflag = (p ? PTF_PRF : 0) | (phys ? PTF_SDPHYS : 0)
358 | PTF_OVFERR;
359 pt->pt_cnt = pt->pt_nsto = 0; /* Initialize */
360
361 /* Stick freelist in table */
362 for(sd = sbx_nfl; sd; sd = sd->slforw)
363 { if(sbe_tbent(pt, sd) < 0)
364 { if(pt->pt_xerr < 0)
365 PRFBAD("SD freelist too long",
366 printf("SD freelist too long (%d)\n",
367 NPTRS))
368 PRFBAD("SD freelist loop",
369 printf("SD freelist loop at %o\n", pt->pt_xerr))
370 }
371
372 if(sd->sdflags)
373 {
374 PRF(printf("Bad free SD, non-zero flag:\n"))
375 PRFBUG("Free SD flagged", sbe_psd(sd))
376 }
377 }
378 pt->pt_hidx = pt->pt_nsto; /* Set idx of 1st non-FL entry */
379 return(0);
380}
381
382
383/* SBE_SCHK(SDptr, tableptr) - Auxiliary for SBE_SDLIST.
384 * If SD not already in table, verifies or prints
385 * the complete physical or logical list it's on, and enters all
386 * of its SDs into table (to prevent doing it again).
387 * Returns 0 if no errors, else error string.
388** There is a problem when the table overflows. The tbent routine
389** wants to add it (wrapping around at bottom) in that case, because
390** that still helps detect loops. But this routine wants to reset
391** the table back (after scanning to head of list) and once it starts
392** scanning forward again it will fail, because some of the SDs are
393** still in the table due to the wraparound! Thus PTF_OVFERR is always
394** set, in order to at least give the right error message.
395*/
396char *
397sbe_schk(sd, pt)
398register struct sdblk *sd;
399struct ptab *pt;
400{ register struct sdblk *sdx;
401 register struct smblk *sm;
402 struct sbfile *savfile;
403 chroff lastaddr;
404 int p, res, savidx, phys;
405
406 phys = pt->pt_pflag&PTF_SDPHYS; /* Set up physflag */
407 if(phys && (sd->sdfile == 0)) /* Ignore non-phys stuff if phys */
408 return(0);
409 p = pt->pt_pflag&PTF_PRF; /* Set up printflag */
410 savidx = pt->pt_nsto; /* Remember initial extent of table */
411
412 if(sbe_tbent(pt, sd) < 0)
413 { if(pt->pt_xerr >= 0) /* OK if already in table */
414 return(0);
415 PRFBAD("Too many SDs",
416 printf("Too many SDs for table (%d)\n", NPTRS))
417 }
418
419 /* Now search backward for start of list */
420 while(sdx = (phys ? sd->sdback : sd->slback))
421 if(sbe_tbent(pt,sdx) >= 0)
422 sd = sdx;
423 else break;
424 if(sdx)
425 { if(pt->pt_xerr < 0) /* Table error? */
426 PRFBAD("Too many SDs",
427 printf("Too many SDs for table (%d)\n",NPTRS))
428 PRF(printf("Backlist loop!! Dup'd node:%s\n",
429 (pt->pt_xerr < pt->pt_hidx) ?
430 "(on freelist!)" : "" ))
431 PRFBUG((phys ? "Phys SD loop" : "SD loop"), sbe_psd(sdx))
432 }
433 /* Reset table to flush nodes backed over */
434 pt->pt_cnt = pt->pt_nsto = savidx;
435
436 /* SD now points to start of list. Begin stepping thru list... */
437 PRF(printf("---- %sList started: ", (phys ? "Phys " : "")))
438 if(phys)
439 { savfile = sd->sdfile;
440 PRF(printf(" SF: %o, fd= %d, ln= %ld\n",
441 savfile,savfile->sffd,savfile->sflen))
442 if(savfile->sfptr1 != sd)
443 PRFBUG("SFPTR1 bad",
444 printf(" BAD!! Sfptr1 %o doesn't match SD %o!!\n",
445 savfile->sfptr1, sd))
446 lastaddr = 0;
447 }
448 else PRF(printf("\n"))
449
450 PRF(printf("%s\n", sdhdline))
451 for(sdx = 0; sd; (sdx = sd, sd = (phys ? sd->sdforw : sd->slforw)))
452 {
453 PRF(sbe_psd(sd)) /* Print it out */
454 if(sdx != (phys ? sd->sdback : sd->slback))
455 { if(phys)
456 PRFBUG("PSD bad sdback",printf("\tBad phys backptr\n"))
457 else
458 PRFBUG("SD bad slback",printf("\tBad backptr\n"))
459 }
460
461 if((sd->sdflags&0377) != SD_NID)
462 PRFBUG("Bad SD node ID", printf("\tBad node ID!\n"))
463
464
465 if(sd->sdfile && (sd->sdlen < 0 || sd->sdaddr < 0))
466 PRFBUG("SD: neg len/addr",
467 printf("\tNeg disk len/addr\n"))
468 if(phys) goto dophys;
469
470 /* Do special stuff for logical list */
471 if(sm = sd->sdmem)
472 { if((sm->smflags&0377) != SM_NID)
473 PRFBUG("SD: bad SM",
474 printf("\nBad SMBLK ptr\n"))
475 if((sd->sdflags&SD_MOD)==0
476 && sd->sdlen != sm->smuse)
477 PRFBUG("SD != SM",
478 printf("\tBad SMBLK? Len conflict\n"))
479 if(sm->smlen < sm->smuse)
480 PRFBUG("SD: SM len < use",
481 printf("\tBad SMBLK, len < use\n"))
482 }
483 goto doboth; /* Skip phys stuff */
484
485 /* Do special stuff for phys list */
486 dophys: if(sd->sdfile != savfile)
487 PRFBUG("SD: bad sdfile",
488 printf("\tBad sdfile ptr! Shd be %o\n",
489 savfile))
490 if(sd->sdaddr < lastaddr)
491 PRFBUG("SD addr out of order",
492 printf("\tBad disk addr, not in order!\n"))
493 lastaddr = sd->sdaddr;
494 /* Done with special phys stuff */
495
496 doboth: if(sbe_tbent(pt, sd) < 0)
497 { if(pt->pt_xerr < 0)
498 PRFBAD("Too many SDs",
499 printf("Too many SDs for table (%d)\n",NPTRS))
500
501 PRFBUG("SD loop",
502 printf("\tLOOP!! This SD already seen%s.\n",
503 (pt->pt_xerr < pt->pt_hidx) ?
504 " (on freelist!)" : "" ))
505 break;
506 }
507 }
508 PRF(printf("-----------\n"))
509 return(0);
510}
511
512
513/* SBE_DSK(SFptr) - Print out disk usage list for specific file
514 */
515
516sbe_dsk(sfp)
517SBFILE *sfp;
518{
519 printf("SBFILE printout not coded: %o\n",sfp);
520}
521
522
523/* SBBUF structure debugging routines */
524
525struct flgt sbflgtab[] = {
526 SB_OVW, 'O',
527 SB_WRIT,'W',
528 0,0
529};
530static char sbfhelp[] = "O-Overwrite, W-Write";
531
532/* SBE_SBVFY(SBptr) - Verify a SB-string.
533 * Returns error message (0 if no errors found).
534 */
535char *
536sbe_sbvfy(sbp)
537SBBUF *sbp;
538{ return(sbe_sbs(sbp,0));
539}
540
541/* SBE_SBS(SBptr, printflag) - Verify/Print SBSTR data stuff
542 * Returns error message (0 if no errors found).
543 */
544char *
545sbe_sbs(sbp,p)
546SBBUF *sbp;
547int p;
548{ register SBBUF *sb;
549 register struct smblk *sm;
550 register struct sdblk *sd;
551
552 sb = sbp;
553 PRF(printf("SBSTR %o: ",sb))
554 if(sb == 0)
555 PRFBUG(0,printf("Zero pointer???\n"))
556
557 /* First print out cryptic summary in case pointers bomb
558 * out farther on. */
559 PRF(printf(" (io,cur,r,w,f,.,+ = %o,%o,%d,%d,%o,%lo,%lo)\n",
560 sb->sbiop, sb->sbcur, sb->sbrleft, sb->sbwleft,
561 sb->sbflags, sb->sbdot, sb->sboff))
562
563 PRF(printf(" sbflags %5o = %s (%s)\n",
564 sb->sbflags, sbe_fstr(sb->sbflags,sbflgtab),
565 sbfhelp))
566
567 if(sd = sb->sbcur) /* Okay, now try getting pointers */
568 sm = sd->sdmem;
569 else sm = 0;
570
571 PRF(printf(" sbcur %6o",sd))
572 if(sd)
573 {
574 PRF(printf("\n %s\n ", sdhdline))
575 PRF(sbe_psd(sd))
576
577 if((sd->sdflags&0377) != SD_NID)
578 PRFBUG("SBCUR not SD?",printf(" BAD SDBLK ID!! \n"))
579 if(sm)
580 {
581 PRF(printf(" %s\n ", smhdline))
582 PRF(sbe_smp(sm,0))
583 if((sm->smflags&0377) != SM_NID)
584 PRFBUG("SBCUR has bad SM",
585 printf(" BAD SMBLK ID!!\n"))
586 }
587 }
588
589
590 PRF(printf(" sbiop %6o",sb->sbiop))
591 if(sb->sbiop)
592 { if(!sm || sb->sbiop < sm->smaddr
593 || sb->sbiop > (sm->smaddr + sm->smlen))
594 PRFBUG("Bad SBIOP", printf(" BAD"))
595 }
596 else if(sb->sbrleft > 0 || sb->sbwleft > 0)
597 PRFBUG("Bad SBIOP/cnts", printf(" BAD"))
598 PRF(printf("\n"))
599
600 PRF(printf(" sbrleft %5o = %5d.",sb->sbrleft, sb->sbrleft))
601 if(sb->sbrleft
602 && ( !sm
603 || sb->sbwleft
604 || (sb->sbflags&SB_WRIT)
605 || (sb->sbrleft != (sm->smuse - (sb->sbiop - sm->smaddr)))
606 ))
607 PRFBUG("Bad sbrleft", printf(" BAD"))
608 PRF(printf("\n"))
609
610 PRF(printf(" sbwleft %5o = %5d.", sb->sbwleft, sb->sbwleft))
611 if(sb->sbwleft
612 && ( !sm
613 || (sb->sbflags&SB_WRIT) == 0
614 || (sb->sbwleft > (sm->smlen - (sb->sbiop - sm->smaddr)))
615 ))
616 PRFBUG("Bad sbwleft", printf(" BAD"))
617 PRF(printf("\n"))
618
619 PRF(printf(" sbdot %7lo = %7ld.", sb->sbdot, sb->sbdot))
620 if(sb->sbdot < 0)
621 PRFBUG("Bad sbdot", printf(" BAD"))
622
623 PRF(printf("\n sboff %7lo = %7ld.\n", sb->sboff, sb->sboff))
624 PRF(printf(" I/O ptr loc: %ld.\n\n", sb_tell(sb)))
625
626 return(0);
627}
628
629
630/* SBE_TBENT() - Auxiliary to add and check entries to a pointer table.
631 * Note we assume here that smblk ptrs are used, although sdblks
632 * can also be hacked. This wins as long as the two kinds of ptrs
633 * are basically identical (saves horrible casting problems).
634 * Returns index # if successful (between 0 and NPTRS-1 inclusive).
635 * Otherwise an error (-1), with relevant info in pt_xerr:
636 * -1 if out of room and flag set making it an error
637 * 0-n if entry already existed.
638 */
639sbe_tbent(pt, sm)
640register struct ptab *pt;
641struct smblk *sm;
642{ register struct smblk **smt;
643 register int i;
644 int p;
645
646 p = pt->pt_pflag&PTF_PRF; /* Set up print flag */
647 smt = &(pt->pt_tab[0]);
648 if(i = pt->pt_nsto)
649 { do {
650 if(sm == *smt++)
651 { pt->pt_xerr = pt->pt_nsto - i;
652 return(-1);
653 }
654 } while(--i);
655 --smt;
656 }
657
658 i = pt->pt_cnt++;
659 if(++(pt->pt_nsto) > NPTRS)
660 { if(pt->pt_pflag&PTF_OVFERR)
661 { pt->pt_err = "Ptrtab overflow";
662 pt->pt_xerr = -1;
663 return(-1);
664 }
665 pt->pt_nsto = NPTRS;
666 i %= NPTRS;
667 }
668 pt->pt_tab[i] = sm;
669 return(i);
670}
671
672/* SBE_FSTR(flags, flagtab) - Auxiliary to convert flag word to a string
673 * and return pointer to it. Handy for printfs.
674 */
675char *
676sbe_fstr(flags, fp)
677register int flags;
678register struct flgt *fp;
679{ static char retstr[17]; /* Max of 16 flags */
680 register char *cp;
681 cp = retstr;
682 for(; fp->flg_bit; ++fp)
683 *cp++ = (fp->flg_bit&flags) ? fp->flg_chr : ' ';
684 *cp = 0;
685 return(retstr);
686}
Note: See TracBrowser for help on using the repository browser.