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.5 (Berkeley) 06/18/90"; 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 ((rn = iop->_ptr - base) >= iop->_bufsiz || c == '\n') { 39 iop->_ptr = base; 40 iop->_cnt = 0; 41 } else { 42 /* we got here because _cnt is wrong, so fix it */ 43 iop->_cnt = -rn; 44 rn = n = 0; 45 } 46 } else if (iop->_flag&_IONBF) { 47 c1 = c; 48 rn = 1; 49 base = &c1; 50 iop->_cnt = 0; 51 } else { 52 if ((base=iop->_base)==NULL) { 53 if (fstat(fileno(iop), &stbuf) < 0 || 54 stbuf.st_blksize <= NULL) 55 size = BUFSIZ; 56 else 57 size = stbuf.st_blksize; 58 if ((iop->_base=base=malloc(size)) == NULL) { 59 iop->_flag |= _IONBF; 60 goto tryagain; 61 } 62 iop->_flag |= _IOMYBUF; 63 iop->_bufsiz = size; 64 if (iop==stdout && isatty(fileno(stdout))) { 65 iop->_flag |= _IOLBF; 66 iop->_ptr = base; 67 goto tryagain; 68 } 69 rn = n = 0; 70 } else 71 rn = iop->_ptr - base; 72 iop->_ptr = base; 73 iop->_cnt = iop->_bufsiz; 74 } 75 while (rn > 0) { 76 if ((n = write(fileno(iop), base, rn)) <= 0) { 77 iop->_flag |= _IOERR; 78 return(EOF); 79 } 80 rn -= n; 81 base += n; 82 } 83 if ((iop->_flag&(_IOLBF|_IONBF)) == 0) { 84 iop->_cnt--; 85 *iop->_ptr++ = c; 86 } 87 return(c); 88 } 89 90 fpurge(iop) 91 register FILE *iop; 92 { 93 iop->_ptr = iop->_base; 94 iop->_cnt = iop->_flag&(_IOLBF|_IONBF|_IOREAD) ? 0 : iop->_bufsiz; 95 return(0); 96 } 97 98 fflush(iop) 99 register FILE *iop; 100 { 101 register char *base; 102 register n, rn; 103 104 if ((iop->_flag&(_IONBF|_IOWRT))==_IOWRT && 105 (base = iop->_base) != NULL && (rn = n = iop->_ptr - base) > 0) { 106 iop->_ptr = base; 107 iop->_cnt = (iop->_flag&(_IOLBF|_IONBF)) ? 0 : iop->_bufsiz; 108 do { 109 if ((n = write(fileno(iop), base, rn)) <= 0) { 110 iop->_flag |= _IOERR; 111 return(EOF); 112 } 113 rn -= n; 114 base += n; 115 } while (rn > 0); 116 } 117 return(0); 118 } 119 120 fclose(iop) 121 register FILE *iop; 122 { 123 register int r; 124 125 r = EOF; 126 if (iop->_flag&(_IOREAD|_IOWRT|_IORW) && (iop->_flag&_IOSTRG)==0) { 127 r = fflush(iop); 128 if (close(fileno(iop)) < 0) 129 r = EOF; 130 if (iop->_flag&_IOMYBUF) 131 free(iop->_base); 132 } 133 iop->_cnt = 0; 134 iop->_base = (char *)NULL; 135 iop->_ptr = (char *)NULL; 136 iop->_bufsiz = 0; 137 iop->_flag = 0; 138 iop->_file = 0; 139 return(r); 140 } 141 142 _cleanup() 143 { 144 extern int _fwalk(); 145 146 _fwalk(fclose); 147 } 148