xref: /original-bsd/lib/libc/stdio/filbuf.c (revision 8f08e272)
1 /* @(#)filbuf.c	4.9 (Berkeley) 06/21/84 */
2 #include	<stdio.h>
3 #include	<sys/types.h>
4 #include	<sys/stat.h>
5 char	*malloc();
6 
7 _filbuf(iop)
8 register FILE *iop;
9 {
10 	int size;
11 	struct stat stbuf;
12 	static char smallbuf[_NFILE];
13 
14 	if (iop->_flag & _IORW)
15 		iop->_flag |= _IOREAD;
16 
17 	if ((iop->_flag&_IOREAD) == 0)
18 		return(EOF);
19 	if (iop->_flag&(_IOSTRG|_IOEOF))
20 		return(EOF);
21 tryagain:
22 	if (iop->_base==NULL) {
23 		if (iop->_flag&_IONBF) {
24 			iop->_base = &smallbuf[fileno(iop)];
25 			goto tryagain;
26 		}
27 		if (fstat(fileno(iop), &stbuf) < 0 || stbuf.st_blksize <= NULL)
28 			size = BUFSIZ;
29 		else
30 			size = stbuf.st_blksize;
31 		if ((iop->_base = malloc(size)) == NULL) {
32 			iop->_flag |= _IONBF;
33 			goto tryagain;
34 		}
35 		iop->_flag |= _IOMYBUF;
36 		iop->_bufsiz = size;
37 	}
38 	if (iop == stdin) {
39 		if (stdout->_flag&_IOLBF)
40 			fflush(stdout);
41 		if (stderr->_flag&_IOLBF)
42 			fflush(stderr);
43 	}
44 	iop->_cnt = read(fileno(iop), iop->_base,
45 		iop->_flag & _IONBF ? 1 : iop->_bufsiz);
46 	iop->_ptr = iop->_base;
47 	if (--iop->_cnt < 0) {
48 		if (iop->_cnt == -1) {
49 			iop->_flag |= _IOEOF;
50 			if (iop->_flag & _IORW)
51 				iop->_flag &= ~_IOREAD;
52 		} else
53 			iop->_flag |= _IOERR;
54 		iop->_cnt = 0;
55 		return(-1);
56 	}
57 	return(*iop->_ptr++&0377);
58 }
59