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