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