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