1*46111Sbostic /*- 2*46111Sbostic * Copyright (c) 1990 The Regents of the University of California. 3*46111Sbostic * All rights reserved. 4*46111Sbostic * 5*46111Sbostic * This code is derived from software contributed to Berkeley by 6*46111Sbostic * Chris Torek. 7*46111Sbostic * 8*46111Sbostic * %sccs.include.redist.c% 9*46111Sbostic */ 10*46111Sbostic 11*46111Sbostic #if defined(LIBC_SCCS) && !defined(lint) 12*46111Sbostic static char sccsid[] = "@(#)makebuf.c 5.1 (Berkeley) 01/20/91"; 13*46111Sbostic #endif /* LIBC_SCCS and not lint */ 14*46111Sbostic 15*46111Sbostic #include <sys/types.h> 16*46111Sbostic #include <sys/stat.h> 17*46111Sbostic #include <stdio.h> 18*46111Sbostic #include <stdlib.h> 19*46111Sbostic #include "local.h" 20*46111Sbostic 21*46111Sbostic /* 22*46111Sbostic * Allocate a file buffer, or switch to unbuffered I/O. 23*46111Sbostic * Per the ANSI C standard, ALL tty devices default to line buffered. 24*46111Sbostic * 25*46111Sbostic * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek 26*46111Sbostic * optimisation) right after the fstat() that finds the buffer size. 27*46111Sbostic */ 28*46111Sbostic void 29*46111Sbostic __smakebuf(fp) 30*46111Sbostic register FILE *fp; 31*46111Sbostic { 32*46111Sbostic register size_t size, couldbetty; 33*46111Sbostic register void *p; 34*46111Sbostic struct stat st; 35*46111Sbostic 36*46111Sbostic if (fp->_flags & __SNBF) { 37*46111Sbostic fp->_bf._base = fp->_p = fp->_nbuf; 38*46111Sbostic fp->_bf._size = 1; 39*46111Sbostic return; 40*46111Sbostic } 41*46111Sbostic if (fp->_file < 0 || fstat(fp->_file, &st) < 0) { 42*46111Sbostic couldbetty = 0; 43*46111Sbostic size = BUFSIZ; 44*46111Sbostic /* do not try to optimise fseek() */ 45*46111Sbostic fp->_flags |= __SNPT; 46*46111Sbostic } else { 47*46111Sbostic couldbetty = (st.st_mode & S_IFMT) == S_IFCHR; 48*46111Sbostic size = st.st_blksize <= 0 ? BUFSIZ : st.st_blksize; 49*46111Sbostic /* 50*46111Sbostic * Optimise fseek() only if it is a regular file. 51*46111Sbostic * (The test for __sseek is mainly paranoia.) 52*46111Sbostic */ 53*46111Sbostic if ((st.st_mode & S_IFMT) == S_IFREG && 54*46111Sbostic fp->_seek == __sseek) { 55*46111Sbostic fp->_flags |= __SOPT; 56*46111Sbostic fp->_blksize = st.st_blksize; 57*46111Sbostic } else 58*46111Sbostic fp->_flags |= __SNPT; 59*46111Sbostic } 60*46111Sbostic if ((p = malloc(size)) == NULL) { 61*46111Sbostic fp->_flags |= __SNBF; 62*46111Sbostic fp->_bf._base = fp->_p = fp->_nbuf; 63*46111Sbostic fp->_bf._size = 1; 64*46111Sbostic } else { 65*46111Sbostic __cleanup = _cleanup; 66*46111Sbostic fp->_flags |= __SMBF; 67*46111Sbostic fp->_bf._base = fp->_p = p; 68*46111Sbostic fp->_bf._size = size; 69*46111Sbostic if (couldbetty && isatty(fp->_file)) 70*46111Sbostic fp->_flags |= __SLBF; 71*46111Sbostic } 72*46111Sbostic } 73