xref: /inferno-os/libbio/binit.c (revision 72335078034e3cd7edcb1739556b405a3e1e9bf8)
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
batexit(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
deinstall(Biobuf * bp)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
install(Biobuf * bp)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
Binits(Biobuf * bp,int f,int mode,uchar * p,int size)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
Binit(Biobuf * bp,int f,int mode)95 Binit(Biobuf *bp, int f, int mode)
96 {
97 	return Binits(bp, f, mode, bp->b, sizeof(bp->b));
98 }
99 
100 Biobuf*
Bopen(char * name,int mode)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
Bterm(Biobuf * bp)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