xref: /plan9/sys/src/libbio/binit.c (revision efc4291f9554edd4b2b0148fe3a05435b4507286)
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