xref: /csrg-svn/lib/libc/stdio/wbuf.c (revision 16571)
1*16571Sralph /* @(#)wbuf.c	4.7 (Berkeley) 06/06/84 */
22003Swnj #include	<stdio.h>
38326Smckusick #include	<sys/types.h>
48326Smckusick #include	<sys/stat.h>
52003Swnj 
62003Swnj char	*malloc();
72003Swnj 
82003Swnj _flsbuf(c, iop)
92003Swnj register FILE *iop;
102003Swnj {
112003Swnj 	register char *base;
122003Swnj 	register n, rn;
132003Swnj 	char c1;
148326Smckusick 	int size;
158326Smckusick 	struct stat stbuf;
162003Swnj 
173163Stoy 	if (iop->_flag & _IORW) {
183163Stoy 		iop->_flag |= _IOWRT;
1913493Ssam 		iop->_flag &= ~(_IOEOF|_IOREAD);
203163Stoy 	}
213163Stoy 
222003Swnj 	if ((iop->_flag&_IOWRT)==0)
232003Swnj 		return(EOF);
242003Swnj tryagain:
252003Swnj 	if (iop->_flag&_IOLBF) {
262003Swnj 		base = iop->_base;
272003Swnj 		*iop->_ptr++ = c;
288326Smckusick 		if (iop->_ptr >= base+iop->_bufsiz || c == '\n') {
292003Swnj 			n = write(fileno(iop), base, rn = iop->_ptr - base);
302003Swnj 			iop->_ptr = base;
312003Swnj 		} else
322003Swnj 			rn = n = 0;
332003Swnj 		iop->_cnt = 0;
342003Swnj 	} else if (iop->_flag&_IONBF) {
352003Swnj 		c1 = c;
362003Swnj 		rn = 1;
372003Swnj 		n = write(fileno(iop), &c1, rn);
382003Swnj 		iop->_cnt = 0;
392003Swnj 	} else {
402003Swnj 		if ((base=iop->_base)==NULL) {
418326Smckusick 			if (fstat(fileno(iop), &stbuf) < 0 ||
428326Smckusick 			    stbuf.st_blksize <= NULL)
438326Smckusick 				size = BUFSIZ;
448326Smckusick 			else
458326Smckusick 				size = stbuf.st_blksize;
468326Smckusick 			if ((iop->_base=base=malloc(size)) == NULL) {
472003Swnj 				iop->_flag |= _IONBF;
482003Swnj 				goto tryagain;
492003Swnj 			}
502003Swnj 			iop->_flag |= _IOMYBUF;
518326Smckusick 			iop->_bufsiz = size;
52*16571Sralph 			if (iop==stdout && isatty(fileno(stdout))) {
53*16571Sralph 				iop->_flag |= _IOLBF;
54*16571Sralph 				iop->_ptr = base;
55*16571Sralph 				goto tryagain;
56*16571Sralph 			}
572003Swnj 			rn = n = 0;
582003Swnj 		} else if ((rn = n = iop->_ptr - base) > 0) {
592003Swnj 			iop->_ptr = base;
602003Swnj 			n = write(fileno(iop), base, n);
612003Swnj 		}
628326Smckusick 		iop->_cnt = iop->_bufsiz-1;
632003Swnj 		*base++ = c;
642003Swnj 		iop->_ptr = base;
652003Swnj 	}
662003Swnj 	if (rn != n) {
672003Swnj 		iop->_flag |= _IOERR;
682003Swnj 		return(EOF);
692003Swnj 	}
702003Swnj 	return(c);
712003Swnj }
722003Swnj 
732003Swnj fflush(iop)
742003Swnj register struct _iobuf *iop;
752003Swnj {
762003Swnj 	register char *base;
772003Swnj 	register n;
782003Swnj 
792003Swnj 	if ((iop->_flag&(_IONBF|_IOWRT))==_IOWRT
802003Swnj 	 && (base=iop->_base)!=NULL && (n=iop->_ptr-base)>0) {
812003Swnj 		iop->_ptr = base;
828326Smckusick 		iop->_cnt = (iop->_flag&(_IOLBF|_IONBF)) ? 0 : iop->_bufsiz;
832003Swnj 		if (write(fileno(iop), base, n)!=n) {
842003Swnj 			iop->_flag |= _IOERR;
852003Swnj 			return(EOF);
862003Swnj 		}
872003Swnj 	}
882003Swnj 	return(0);
892003Swnj }
902003Swnj 
912003Swnj /*
922003Swnj  * Flush buffers on exit
932003Swnj  */
942003Swnj 
952003Swnj _cleanup()
962003Swnj {
972003Swnj 	register struct _iobuf *iop;
982003Swnj 	extern struct _iobuf *_lastbuf;
992003Swnj 
1002003Swnj 	for (iop = _iob; iop < _lastbuf; iop++)
1012003Swnj 		fclose(iop);
1022003Swnj }
1032003Swnj 
1042003Swnj fclose(iop)
1059739Ssam 	register struct _iobuf *iop;
1062003Swnj {
1079721Sclemc 	register int r;
1082003Swnj 
1092003Swnj 	r = EOF;
1103163Stoy 	if (iop->_flag&(_IOREAD|_IOWRT|_IORW) && (iop->_flag&_IOSTRG)==0) {
1112003Swnj 		r = fflush(iop);
1122003Swnj 		if (close(fileno(iop)) < 0)
1132003Swnj 			r = EOF;
1142003Swnj 		if (iop->_flag&_IOMYBUF)
1152003Swnj 			free(iop->_base);
1162003Swnj 	}
1172003Swnj 	iop->_cnt = 0;
1189721Sclemc 	iop->_base = (char *)NULL;
1199721Sclemc 	iop->_ptr = (char *)NULL;
1209721Sclemc 	iop->_bufsiz = 0;
1219721Sclemc 	iop->_flag = 0;
1229721Sclemc 	iop->_file = 0;
1232003Swnj 	return(r);
1242003Swnj }
125