xref: /original-bsd/lib/libc/stdio/filbuf.c (revision 43bfbc1c)
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[] = "@(#)filbuf.c	5.3 (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 char	*malloc();
15 
16 _filbuf(iop)
17 register FILE *iop;
18 {
19 	int size;
20 	struct stat stbuf;
21 	extern char *_smallbuf;
22 	char c;
23 
24 	if (iop->_flag & _IORW)
25 		iop->_flag |= _IOREAD;
26 
27 	if ((iop->_flag&_IOREAD) == 0)
28 		return(EOF);
29 	if (iop->_flag&(_IOSTRG|_IOEOF))
30 		return(EOF);
31 tryagain:
32 	if (iop->_base==NULL) {
33 		if (iop->_flag&_IONBF) {
34 			iop->_base = _smallbuf ? &_smallbuf[fileno(iop)] : &c;
35 			goto tryagain;
36 		}
37 		if (fstat(fileno(iop), &stbuf) < 0 || stbuf.st_blksize <= NULL)
38 			size = BUFSIZ;
39 		else
40 			size = stbuf.st_blksize;
41 		if ((iop->_base = malloc(size)) == NULL) {
42 			iop->_flag |= _IONBF;
43 			goto tryagain;
44 		}
45 		iop->_flag |= _IOMYBUF;
46 		iop->_bufsiz = size;
47 	}
48 	if (iop == stdin) {
49 		if (stdout->_flag&_IOLBF)
50 			fflush(stdout);
51 		if (stderr->_flag&_IOLBF)
52 			fflush(stderr);
53 	}
54 	iop->_cnt = read(fileno(iop), iop->_base,
55 		iop->_flag & _IONBF ? 1 : iop->_bufsiz);
56 	iop->_ptr = iop->_base;
57 	if (iop->_flag & _IONBF && iop->_base == &c)
58 		iop->_base = NULL;
59 	if (--iop->_cnt < 0) {
60 		if (iop->_cnt == -1) {
61 			iop->_flag |= _IOEOF;
62 			if (iop->_flag & _IORW)
63 				iop->_flag &= ~_IOREAD;
64 		} else
65 			iop->_flag |= _IOERR;
66 		iop->_cnt = 0;
67 		return(EOF);
68 	}
69 	return(*iop->_ptr++&0377);
70 }
71