xref: /csrg-svn/lib/libc/stdio/wbuf.c (revision 2003)
1*2003Swnj /* @(#)wbuf.c	4.1 (Berkeley) 12/21/80 */
2*2003Swnj #include	<stdio.h>
3*2003Swnj 
4*2003Swnj char	*malloc();
5*2003Swnj 
6*2003Swnj _flsbuf(c, iop)
7*2003Swnj register FILE *iop;
8*2003Swnj {
9*2003Swnj 	register char *base;
10*2003Swnj 	register n, rn;
11*2003Swnj 	char c1;
12*2003Swnj 	extern char _sobuf[];
13*2003Swnj 
14*2003Swnj 	if ((iop->_flag&_IOWRT)==0)
15*2003Swnj 		return(EOF);
16*2003Swnj tryagain:
17*2003Swnj 	if (iop->_flag&_IOLBF) {
18*2003Swnj 		base = iop->_base;
19*2003Swnj 		*iop->_ptr++ = c;
20*2003Swnj 		if (iop->_ptr >= base+BUFSIZ || c == '\n') {
21*2003Swnj 			n = write(fileno(iop), base, rn = iop->_ptr - base);
22*2003Swnj 			iop->_ptr = base;
23*2003Swnj 		} else
24*2003Swnj 			rn = n = 0;
25*2003Swnj 		iop->_cnt = 0;
26*2003Swnj 	} else if (iop->_flag&_IONBF) {
27*2003Swnj 		c1 = c;
28*2003Swnj 		rn = 1;
29*2003Swnj 		n = write(fileno(iop), &c1, rn);
30*2003Swnj 		iop->_cnt = 0;
31*2003Swnj 	} else {
32*2003Swnj 		if ((base=iop->_base)==NULL) {
33*2003Swnj 			if (iop==stdout) {
34*2003Swnj 				if (isatty(fileno(stdout)))
35*2003Swnj 					iop->_flag |= _IOLBF;
36*2003Swnj 				iop->_base = _sobuf;
37*2003Swnj 				iop->_ptr = _sobuf;
38*2003Swnj 				goto tryagain;
39*2003Swnj 			}
40*2003Swnj 			if ((iop->_base=base=malloc(BUFSIZ)) == NULL) {
41*2003Swnj 				iop->_flag |= _IONBF;
42*2003Swnj 				goto tryagain;
43*2003Swnj 			}
44*2003Swnj 			iop->_flag |= _IOMYBUF;
45*2003Swnj 			rn = n = 0;
46*2003Swnj 		} else if ((rn = n = iop->_ptr - base) > 0) {
47*2003Swnj 			iop->_ptr = base;
48*2003Swnj 			n = write(fileno(iop), base, n);
49*2003Swnj 		}
50*2003Swnj 		iop->_cnt = BUFSIZ-1;
51*2003Swnj 		*base++ = c;
52*2003Swnj 		iop->_ptr = base;
53*2003Swnj 	}
54*2003Swnj 	if (rn != n) {
55*2003Swnj 		iop->_flag |= _IOERR;
56*2003Swnj 		return(EOF);
57*2003Swnj 	}
58*2003Swnj 	return(c);
59*2003Swnj }
60*2003Swnj 
61*2003Swnj fflush(iop)
62*2003Swnj register struct _iobuf *iop;
63*2003Swnj {
64*2003Swnj 	register char *base;
65*2003Swnj 	register n;
66*2003Swnj 
67*2003Swnj 	if ((iop->_flag&(_IONBF|_IOWRT))==_IOWRT
68*2003Swnj 	 && (base=iop->_base)!=NULL && (n=iop->_ptr-base)>0) {
69*2003Swnj 		iop->_ptr = base;
70*2003Swnj 		iop->_cnt = (iop->_flag&(_IOLBF|_IONBF)) ? 0 : BUFSIZ;
71*2003Swnj 		if (write(fileno(iop), base, n)!=n) {
72*2003Swnj 			iop->_flag |= _IOERR;
73*2003Swnj 			return(EOF);
74*2003Swnj 		}
75*2003Swnj 	}
76*2003Swnj 	return(0);
77*2003Swnj }
78*2003Swnj 
79*2003Swnj /*
80*2003Swnj  * Flush buffers on exit
81*2003Swnj  */
82*2003Swnj 
83*2003Swnj _cleanup()
84*2003Swnj {
85*2003Swnj 	register struct _iobuf *iop;
86*2003Swnj 	extern struct _iobuf *_lastbuf;
87*2003Swnj 
88*2003Swnj 	for (iop = _iob; iop < _lastbuf; iop++)
89*2003Swnj 		fclose(iop);
90*2003Swnj }
91*2003Swnj 
92*2003Swnj fclose(iop)
93*2003Swnj register struct _iobuf *iop;
94*2003Swnj {
95*2003Swnj 	register r;
96*2003Swnj 
97*2003Swnj 	r = EOF;
98*2003Swnj 	if (iop->_flag&(_IOREAD|_IOWRT) && (iop->_flag&_IOSTRG)==0) {
99*2003Swnj 		r = fflush(iop);
100*2003Swnj 		if (close(fileno(iop)) < 0)
101*2003Swnj 			r = EOF;
102*2003Swnj 		if (iop->_flag&_IOMYBUF)
103*2003Swnj 			free(iop->_base);
104*2003Swnj 		if (iop->_flag&(_IOMYBUF|_IONBF|_IOLBF))
105*2003Swnj 			iop->_base = NULL;
106*2003Swnj 	}
107*2003Swnj 	iop->_flag &= ~(_IOREAD|_IOWRT|_IOLBF|_IONBF|_IOMYBUF|_IOERR|_IOEOF|_IOSTRG);
108*2003Swnj 	iop->_cnt = 0;
109*2003Swnj 	return(r);
110*2003Swnj }
111