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