xref: /csrg-svn/lib/libc/stdio/filbuf.c (revision 21401)
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 #ifndef lint
8 static char sccsid[] = "@(#)filbuf.c	5.1 (Berkeley) 05/30/85";
9 #endif 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 	static char *smallbuf;
22 	static int nfiles;
23 	char c;
24 
25 	if (iop->_flag & _IORW)
26 		iop->_flag |= _IOREAD;
27 
28 	if ((iop->_flag&_IOREAD) == 0)
29 		return(EOF);
30 	if (iop->_flag&(_IOSTRG|_IOEOF))
31 		return(EOF);
32 tryagain:
33 	if (iop->_base==NULL) {
34 		if (iop->_flag&_IONBF) {
35 			if (nfiles <= 0)
36 				nfiles = getdtablesize();
37 			if (smallbuf == NULL)
38 				smallbuf = malloc(nfiles * sizeof *smallbuf);
39 			iop->_base = smallbuf ? &smallbuf[fileno(iop)] : &c;
40 			goto tryagain;
41 		}
42 		if (fstat(fileno(iop), &stbuf) < 0 || stbuf.st_blksize <= NULL)
43 			size = BUFSIZ;
44 		else
45 			size = stbuf.st_blksize;
46 		if ((iop->_base = malloc(size)) == NULL) {
47 			iop->_flag |= _IONBF;
48 			goto tryagain;
49 		}
50 		iop->_flag |= _IOMYBUF;
51 		iop->_bufsiz = size;
52 	}
53 	if (iop == stdin) {
54 		if (stdout->_flag&_IOLBF)
55 			fflush(stdout);
56 		if (stderr->_flag&_IOLBF)
57 			fflush(stderr);
58 	}
59 	iop->_cnt = read(fileno(iop), iop->_base,
60 		iop->_flag & _IONBF ? 1 : iop->_bufsiz);
61 	iop->_ptr = iop->_base;
62 	if (iop->_flag & _IONBF && iop->_base == &c)
63 		iop->_base = NULL;
64 	if (--iop->_cnt < 0) {
65 		if (iop->_cnt == -1) {
66 			iop->_flag |= _IOEOF;
67 			if (iop->_flag & _IORW)
68 				iop->_flag &= ~_IOREAD;
69 		} else
70 			iop->_flag |= _IOERR;
71 		iop->_cnt = 0;
72 		return(EOF);
73 	}
74 	return(*iop->_ptr++&0377);
75 }
76