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