xref: /csrg-svn/lib/libc/stdio/wbuf.c (revision 21403)
1*21403Sdist /*
2*21403Sdist  * Copyright (c) 1980 Regents of the University of California.
3*21403Sdist  * All rights reserved.  The Berkeley software License Agreement
4*21403Sdist  * specifies the terms and conditions for redistribution.
5*21403Sdist  */
6*21403Sdist 
7*21403Sdist #ifndef lint
8*21403Sdist static char sccsid[] = "@(#)wbuf.c	5.1 (Berkeley) 05/30/85";
9*21403Sdist #endif not lint
10*21403Sdist 
112003Swnj #include	<stdio.h>
128326Smckusick #include	<sys/types.h>
138326Smckusick #include	<sys/stat.h>
142003Swnj 
152003Swnj char	*malloc();
162003Swnj 
172003Swnj _flsbuf(c, iop)
1817415Sralph unsigned char c;
192003Swnj register FILE *iop;
202003Swnj {
212003Swnj 	register char *base;
222003Swnj 	register n, rn;
232003Swnj 	char c1;
248326Smckusick 	int size;
258326Smckusick 	struct stat stbuf;
262003Swnj 
273163Stoy 	if (iop->_flag & _IORW) {
283163Stoy 		iop->_flag |= _IOWRT;
2913493Ssam 		iop->_flag &= ~(_IOEOF|_IOREAD);
303163Stoy 	}
313163Stoy 
322003Swnj 	if ((iop->_flag&_IOWRT)==0)
332003Swnj 		return(EOF);
342003Swnj tryagain:
352003Swnj 	if (iop->_flag&_IOLBF) {
362003Swnj 		base = iop->_base;
372003Swnj 		*iop->_ptr++ = c;
388326Smckusick 		if (iop->_ptr >= base+iop->_bufsiz || c == '\n') {
392003Swnj 			n = write(fileno(iop), base, rn = iop->_ptr - base);
402003Swnj 			iop->_ptr = base;
4117415Sralph 			iop->_cnt = 0;
422003Swnj 		} else
432003Swnj 			rn = n = 0;
442003Swnj 	} else if (iop->_flag&_IONBF) {
452003Swnj 		c1 = c;
462003Swnj 		rn = 1;
472003Swnj 		n = write(fileno(iop), &c1, rn);
482003Swnj 		iop->_cnt = 0;
492003Swnj 	} else {
502003Swnj 		if ((base=iop->_base)==NULL) {
518326Smckusick 			if (fstat(fileno(iop), &stbuf) < 0 ||
528326Smckusick 			    stbuf.st_blksize <= NULL)
538326Smckusick 				size = BUFSIZ;
548326Smckusick 			else
558326Smckusick 				size = stbuf.st_blksize;
568326Smckusick 			if ((iop->_base=base=malloc(size)) == NULL) {
572003Swnj 				iop->_flag |= _IONBF;
582003Swnj 				goto tryagain;
592003Swnj 			}
602003Swnj 			iop->_flag |= _IOMYBUF;
618326Smckusick 			iop->_bufsiz = size;
6216571Sralph 			if (iop==stdout && isatty(fileno(stdout))) {
6316571Sralph 				iop->_flag |= _IOLBF;
6416571Sralph 				iop->_ptr = base;
6516571Sralph 				goto tryagain;
6616571Sralph 			}
672003Swnj 			rn = n = 0;
682003Swnj 		} else if ((rn = n = iop->_ptr - base) > 0) {
692003Swnj 			iop->_ptr = base;
702003Swnj 			n = write(fileno(iop), base, n);
712003Swnj 		}
728326Smckusick 		iop->_cnt = iop->_bufsiz-1;
732003Swnj 		*base++ = c;
742003Swnj 		iop->_ptr = base;
752003Swnj 	}
762003Swnj 	if (rn != n) {
772003Swnj 		iop->_flag |= _IOERR;
782003Swnj 		return(EOF);
792003Swnj 	}
802003Swnj 	return(c);
812003Swnj }
822003Swnj 
832003Swnj fflush(iop)
8417951Sserge register FILE *iop;
852003Swnj {
862003Swnj 	register char *base;
872003Swnj 	register n;
882003Swnj 
892003Swnj 	if ((iop->_flag&(_IONBF|_IOWRT))==_IOWRT
902003Swnj 	 && (base=iop->_base)!=NULL && (n=iop->_ptr-base)>0) {
912003Swnj 		iop->_ptr = base;
928326Smckusick 		iop->_cnt = (iop->_flag&(_IOLBF|_IONBF)) ? 0 : iop->_bufsiz;
932003Swnj 		if (write(fileno(iop), base, n)!=n) {
942003Swnj 			iop->_flag |= _IOERR;
952003Swnj 			return(EOF);
962003Swnj 		}
972003Swnj 	}
982003Swnj 	return(0);
992003Swnj }
1002003Swnj 
1012003Swnj fclose(iop)
10217951Sserge 	register FILE *iop;
1032003Swnj {
1049721Sclemc 	register int r;
1052003Swnj 
1062003Swnj 	r = EOF;
1073163Stoy 	if (iop->_flag&(_IOREAD|_IOWRT|_IORW) && (iop->_flag&_IOSTRG)==0) {
1082003Swnj 		r = fflush(iop);
1092003Swnj 		if (close(fileno(iop)) < 0)
1102003Swnj 			r = EOF;
1112003Swnj 		if (iop->_flag&_IOMYBUF)
1122003Swnj 			free(iop->_base);
1132003Swnj 	}
1142003Swnj 	iop->_cnt = 0;
1159721Sclemc 	iop->_base = (char *)NULL;
1169721Sclemc 	iop->_ptr = (char *)NULL;
1179721Sclemc 	iop->_bufsiz = 0;
1189721Sclemc 	iop->_flag = 0;
1199721Sclemc 	iop->_file = 0;
1202003Swnj 	return(r);
1212003Swnj }
122