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