]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libbio/binit.c
ether82563: support for i211 with iNVM. (thanks mfny and brennan for testing)
[plan9front.git] / sys / src / libbio / binit.c
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
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
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
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 static int
54 bioread(Biobufhdr *bp, void *v, long n)
55 {
56         return read(bp->fid, v, n);
57 }
58
59 static int
60 biowrite(Biobufhdr *bp, void *v, long n)
61 {
62         return write(bp->fid, v, n);
63 }
64
65 int
66 Binits(Biobufhdr *bp, int f, int mode, uchar *p, int size)
67 {
68         p += Bungetsize;        /* make room for Bungets */
69         size -= Bungetsize;
70
71         switch(mode&~(OCEXEC|ORCLOSE|OTRUNC)) {
72         default:
73                 fprint(2, "Binits: unknown mode %d\n", mode);
74                 return Beof;
75
76         case OREAD:
77                 bp->state = Bractive;
78                 bp->ocount = 0;
79                 bp->iof = bioread;
80                 break;
81
82         case OWRITE:
83                 install(bp);
84                 bp->state = Bwactive;
85                 bp->ocount = -size;
86                 bp->iof = biowrite;
87                 break;
88         }
89         bp->bbuf = p;
90         bp->ebuf = p+size;
91         bp->bsize = size;
92         bp->icount = 0;
93         bp->gbuf = bp->ebuf;
94         bp->fid = f;
95         bp->flag = 0;
96         bp->rdline = 0;
97         bp->offset = 0;
98         bp->runesize = 0;
99         bp->errorf = nil;
100         return 0;
101 }
102
103
104 int
105 Binit(Biobuf *bp, int f, int mode)
106 {
107         return Binits(bp, f, mode, bp->b, sizeof(bp->b));
108 }
109
110 Biobuf*
111 Bfdopen(int fd, int mode)
112 {
113         Biobuf *bp;
114
115         bp = malloc(sizeof(Biobuf));
116         if(bp == nil)
117                 return nil;
118         if(Binits(bp, fd, mode, bp->b, sizeof(bp->b)) != 0){
119                 free(bp);
120                 return nil;
121         }
122         bp->flag = Bmagic;                      /* mark bp open & malloced */
123         setmalloctag(bp, getcallerpc(&fd));
124         return bp;
125 }
126
127 Biobuf*
128 Bopen(char *name, int mode)
129 {
130         Biobuf *bp;
131         int fd;
132
133         switch(mode&~(OCEXEC|ORCLOSE|OTRUNC)) {
134         default:
135                 fprint(2, "Bopen: unknown mode %#x\n", mode);
136                 return nil;
137         case OREAD:
138                 fd = open(name, mode);
139                 break;
140         case OWRITE:
141                 fd = create(name, mode, 0666);
142                 break;
143         }
144         if(fd < 0)
145                 return nil;
146         bp = Bfdopen(fd, mode);
147         if(bp == nil){
148                 close(fd);
149                 return nil;
150         }
151         setmalloctag(bp, getcallerpc(&name));
152         return bp;
153 }
154
155 int
156 Bterm(Biobufhdr *bp)
157 {
158         int r;
159
160         deinstall(bp);
161         r = Bflush(bp);
162         if(bp->flag == Bmagic) {
163                 bp->flag = 0;
164                 close(bp->fid);
165                 bp->fid = -1;                   /* prevent accidents */
166                 free(bp);
167         }
168         /* otherwise opened with Binit(s) */
169         return r;
170 }
171
172 void
173 Biofn(Biobufhdr *bp, int (*f)(Biobufhdr *, void *, long))
174 {
175         if(f == nil)
176                 if(bp->state == Bwactive)
177                         bp->iof = biowrite;
178                 else
179                         bp->iof = bioread;
180         else
181                 bp->iof = f;
182 }