xref: /plan9-contrib/sys/src/libbio/binit.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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 
57 	p += Bungetsize;	/* make room for Bungets */
58 	size -= Bungetsize;
59 
60 	switch(mode) {
61 	default:
62 		fprint(2, "Bopen: 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
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 Bopen(char *name, int mode)
98 {
99 	Biobuf *bp;
100 	int f;
101 
102 	switch(mode) {
103 	default:
104 		fprint(2, "Bopen: unknown mode %d\n", mode);
105 		return 0;
106 
107 	case OREAD:
108 		f = open(name, OREAD);
109 		if(f < 0)
110 			return 0;
111 		break;
112 
113 	case OWRITE:
114 		f = create(name, OWRITE, 0666);
115 		if(f < 0)
116 			return 0;
117 	}
118 	bp = malloc(sizeof(Biobuf));
119 	Binits(bp, f, mode, bp->b, sizeof(bp->b));
120 	bp->flag = Bmagic;
121 	return bp;
122 }
123 
124 int
125 Bterm(Biobufhdr *bp)
126 {
127 
128 	deinstall(bp);
129 	Bflush(bp);
130 	if(bp->flag == Bmagic) {
131 		bp->flag = 0;
132 		close(bp->fid);
133 		free(bp);
134 	}
135 	return 0;
136 }
137