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