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 #if defined(LIBC_SCCS) && !defined(lint) 8 static char sccsid[] = "@(#)wbuf.c 5.4 (Berkeley) 12/19/88"; 9 #endif LIBC_SCCS and not lint 10 11 #include <stdio.h> 12 #include <sys/types.h> 13 #include <sys/stat.h> 14 15 char *malloc(); 16 17 _flsbuf(c, iop) 18 unsigned char c; 19 register FILE *iop; 20 { 21 register char *base; 22 register n, rn; 23 char c1; 24 int size; 25 struct stat stbuf; 26 27 if (iop->_flag & _IORW) { 28 iop->_flag |= _IOWRT; 29 iop->_flag &= ~(_IOEOF|_IOREAD); 30 } 31 32 if ((iop->_flag&_IOWRT)==0) 33 return(EOF); 34 tryagain: 35 if (iop->_flag&_IOLBF) { 36 base = iop->_base; 37 *iop->_ptr++ = c; 38 if (iop->_ptr >= base+iop->_bufsiz || c == '\n') { 39 n = write(fileno(iop), base, rn = iop->_ptr - base); 40 iop->_ptr = base; 41 iop->_cnt = 0; 42 } else 43 rn = n = 0; 44 } else if (iop->_flag&_IONBF) { 45 c1 = c; 46 rn = 1; 47 n = write(fileno(iop), &c1, rn); 48 iop->_cnt = 0; 49 } else { 50 if ((base=iop->_base)==NULL) { 51 if (fstat(fileno(iop), &stbuf) < 0 || 52 stbuf.st_blksize <= NULL) 53 size = BUFSIZ; 54 else 55 size = stbuf.st_blksize; 56 if ((iop->_base=base=malloc(size)) == NULL) { 57 iop->_flag |= _IONBF; 58 goto tryagain; 59 } 60 iop->_flag |= _IOMYBUF; 61 iop->_bufsiz = size; 62 if (iop==stdout && isatty(fileno(stdout))) { 63 iop->_flag |= _IOLBF; 64 iop->_ptr = base; 65 goto tryagain; 66 } 67 rn = n = 0; 68 } else if ((rn = n = iop->_ptr - base) > 0) { 69 iop->_ptr = base; 70 n = write(fileno(iop), base, n); 71 } 72 iop->_cnt = iop->_bufsiz-1; 73 *base++ = c; 74 iop->_ptr = base; 75 } 76 if (rn != n) { 77 iop->_flag |= _IOERR; 78 return(EOF); 79 } 80 return(c); 81 } 82 83 fpurge(iop) 84 register FILE *iop; 85 { 86 iop->_ptr = iop->_base; 87 iop->_cnt = iop->_flag&(_IOLBF|_IONBF|_IOREAD) ? 0 : iop->_bufsiz; 88 return(0); 89 } 90 91 fflush(iop) 92 register FILE *iop; 93 { 94 register char *base; 95 register n; 96 97 if ((iop->_flag&(_IONBF|_IOWRT))==_IOWRT 98 && (base=iop->_base)!=NULL && (n=iop->_ptr-base)>0) { 99 iop->_ptr = base; 100 iop->_cnt = (iop->_flag&(_IOLBF|_IONBF)) ? 0 : iop->_bufsiz; 101 if (write(fileno(iop), base, n)!=n) { 102 iop->_flag |= _IOERR; 103 return(EOF); 104 } 105 } 106 return(0); 107 } 108 109 fclose(iop) 110 register FILE *iop; 111 { 112 register int r; 113 114 r = EOF; 115 if (iop->_flag&(_IOREAD|_IOWRT|_IORW) && (iop->_flag&_IOSTRG)==0) { 116 r = fflush(iop); 117 if (close(fileno(iop)) < 0) 118 r = EOF; 119 if (iop->_flag&_IOMYBUF) 120 free(iop->_base); 121 } 122 iop->_cnt = 0; 123 iop->_base = (char *)NULL; 124 iop->_ptr = (char *)NULL; 125 iop->_bufsiz = 0; 126 iop->_flag = 0; 127 iop->_file = 0; 128 return(r); 129 } 130 131 _cleanup() 132 { 133 extern int _fwalk(); 134 135 _fwalk(fclose); 136 } 137