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