xref: /original-bsd/lib/libc/stdio/filbuf.c (revision f0fd5f8a)
1 /* @(#)filbuf.c	4.4 (Berkeley) 10/05/82 */
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 && (stdout->_flag&_IOLBF))
44 		fflush(stdout);
45 	iop->_cnt = read(fileno(iop), iop->_base,
46 		iop->_flag & _IONBF ? 1 : iop->_bufsiz);
47 	iop->_ptr = iop->_base;
48 	if (--iop->_cnt < 0) {
49 		if (iop->_cnt == -1) {
50 			iop->_flag |= _IOEOF;
51 			if (iop->_flag & _IORW)
52 				iop->_flag &= ~_IOREAD;
53 		} else
54 			iop->_flag |= _IOERR;
55 		iop->_cnt = 0;
56 		return(-1);
57 	}
58 	return(*iop->_ptr++&0377);
59 }
60