1 #include "lib9.h" 2 #include <bio.h> 3 4 enum 5 { 6 MAXBUFS = 20 7 }; 8 9 static Biobuf* wbufs[MAXBUFS]; 10 static int atexitflag; 11 12 static 13 void 14 batexit(void) 15 { 16 Biobuf *bp; 17 int i; 18 19 for(i=0; i<nelem(wbufs); i++) { 20 bp = wbufs[i]; 21 if(bp != 0) { 22 wbufs[i] = 0; 23 Bflush(bp); 24 } 25 } 26 } 27 28 static 29 void 30 deinstall(Biobuf *bp) 31 { 32 int i; 33 34 for(i=0; i<nelem(wbufs); i++) 35 if(wbufs[i] == bp) 36 wbufs[i] = 0; 37 } 38 39 static 40 void 41 install(Biobuf *bp) 42 { 43 int i; 44 45 deinstall(bp); 46 for(i=0; i<nelem(wbufs); i++) 47 if(wbufs[i] == 0) { 48 wbufs[i] = bp; 49 break; 50 } 51 if(atexitflag == 0) { 52 atexitflag = 1; 53 atexit(batexit); 54 } 55 } 56 57 int 58 Binits(Biobuf *bp, int f, int mode, uchar *p, int size) 59 { 60 61 p += Bungetsize; /* make room for Bungets */ 62 size -= Bungetsize; 63 64 switch(mode&~(OCEXEC|ORCLOSE|OTRUNC)) { 65 default: 66 fprint(2, "Bopen: unknown mode %d\n", mode); 67 return Beof; 68 69 case OREAD: 70 bp->state = Bractive; 71 bp->ocount = 0; 72 break; 73 74 case OWRITE: 75 install(bp); 76 bp->state = Bwactive; 77 bp->ocount = -size; 78 break; 79 } 80 bp->bbuf = p; 81 bp->ebuf = p+size; 82 bp->bsize = size; 83 bp->icount = 0; 84 bp->gbuf = bp->ebuf; 85 bp->fid = f; 86 bp->flag = 0; 87 bp->rdline = 0; 88 bp->offset = 0; 89 bp->runesize = 0; 90 return 0; 91 } 92 93 94 int 95 Binit(Biobuf *bp, int f, int mode) 96 { 97 return Binits(bp, f, mode, bp->b, sizeof(bp->b)); 98 } 99 100 Biobuf* 101 Bopen(char *name, int mode) 102 { 103 Biobuf *bp; 104 int f; 105 106 switch(mode&~(OCEXEC|ORCLOSE|OTRUNC)) { 107 default: 108 fprint(2, "Bopen: unknown mode %d\n", mode); 109 return 0; 110 111 case OREAD: 112 f = open(name, OREAD); 113 break; 114 115 case OWRITE: 116 f = create(name, mode, 0666); 117 break; 118 } 119 if(f < 0) 120 return 0; 121 bp = malloc(sizeof(Biobuf)); 122 if(bp == nil) 123 return 0; 124 Binits(bp, f, mode, bp->b, sizeof(bp->b)); 125 bp->flag = Bmagic; 126 return bp; 127 } 128 129 int 130 Bterm(Biobuf *bp) 131 { 132 int r; 133 134 deinstall(bp); 135 r = Bflush(bp); 136 if(bp->flag == Bmagic) { 137 bp->flag = 0; 138 close(bp->fid); 139 bp->fid = -1; /* prevent accidents */ 140 free(bp); 141 } 142 /* otherwise opened with Binit(s) */ 143 return r; 144 } 145