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