1 /* @(#)wbuf.c 4.4 (Berkeley) 12/15/82 */ 2 #include <stdio.h> 3 #include <sys/types.h> 4 #include <sys/stat.h> 5 6 char *malloc(); 7 8 _flsbuf(c, iop) 9 register FILE *iop; 10 { 11 register char *base; 12 register n, rn; 13 char c1; 14 int size; 15 struct stat stbuf; 16 extern char _sobuf[]; 17 18 if (iop->_flag & _IORW) { 19 iop->_flag |= _IOWRT; 20 iop->_flag &= ~_IOEOF; 21 } 22 23 if ((iop->_flag&_IOWRT)==0) 24 return(EOF); 25 tryagain: 26 if (iop->_flag&_IOLBF) { 27 base = iop->_base; 28 *iop->_ptr++ = c; 29 if (iop->_ptr >= base+iop->_bufsiz || c == '\n') { 30 n = write(fileno(iop), base, rn = iop->_ptr - base); 31 iop->_ptr = base; 32 } else 33 rn = n = 0; 34 iop->_cnt = 0; 35 } else if (iop->_flag&_IONBF) { 36 c1 = c; 37 rn = 1; 38 n = write(fileno(iop), &c1, rn); 39 iop->_cnt = 0; 40 } else { 41 if ((base=iop->_base)==NULL) { 42 if (fstat(fileno(iop), &stbuf) < 0 || 43 stbuf.st_blksize <= NULL) 44 size = BUFSIZ; 45 else 46 size = stbuf.st_blksize; 47 if (iop==stdout) { 48 if (isatty(fileno(stdout))) 49 iop->_flag |= _IOLBF; 50 iop->_base = _sobuf; 51 iop->_ptr = _sobuf; 52 iop->_bufsiz = size; 53 goto tryagain; 54 } 55 if ((iop->_base=base=malloc(size)) == NULL) { 56 iop->_flag |= _IONBF; 57 goto tryagain; 58 } 59 iop->_flag |= _IOMYBUF; 60 iop->_bufsiz = size; 61 rn = n = 0; 62 } else if ((rn = n = iop->_ptr - base) > 0) { 63 iop->_ptr = base; 64 n = write(fileno(iop), base, n); 65 } 66 iop->_cnt = iop->_bufsiz-1; 67 *base++ = c; 68 iop->_ptr = base; 69 } 70 if (rn != n) { 71 iop->_flag |= _IOERR; 72 return(EOF); 73 } 74 return(c); 75 } 76 77 fflush(iop) 78 register struct _iobuf *iop; 79 { 80 register char *base; 81 register n; 82 83 if ((iop->_flag&(_IONBF|_IOWRT))==_IOWRT 84 && (base=iop->_base)!=NULL && (n=iop->_ptr-base)>0) { 85 iop->_ptr = base; 86 iop->_cnt = (iop->_flag&(_IOLBF|_IONBF)) ? 0 : iop->_bufsiz; 87 if (write(fileno(iop), base, n)!=n) { 88 iop->_flag |= _IOERR; 89 return(EOF); 90 } 91 } 92 return(0); 93 } 94 95 /* 96 * Flush buffers on exit 97 */ 98 99 _cleanup() 100 { 101 register struct _iobuf *iop; 102 extern struct _iobuf *_lastbuf; 103 104 for (iop = _iob; iop < _lastbuf; iop++) 105 fclose(iop); 106 } 107 108 /* 109 * fclose(*iop) - Close an open stdio stream without side effects. 110 * 111 * As per Dennis Ricthie's mail, fclose is defined to leave in a "virgin" state, 112 * the structure pointed to by the parameter, *iop. This means that 113 * all flags are cleared, counters set to 0 and Pointers set to NULL. 114 * 115 * Which implies: 116 * foo = fopen... 117 * setbuf (foo, some_buffer); 118 * ..... 119 * fclose(foo); 120 * 121 * Will leave the buffer stucture cleared. If the user wishes to 122 * reuse the *iop (foo) when he opens another file he must AGAIN call setbuf(3) 123 * if he again wishes to supply his own buffer. 124 * 125 * The old method allowed the above case but had a nasty side effect 126 * of leaving data around if the phase of the moon was right. The correct 127 * solution is to sanitize everything with the fclose. 128 * Clem Cole 12-15-82 129 */ 130 131 fclose(iop) 132 register struct _iobuf *iop; 133 { 134 register int r; 135 136 r = EOF; 137 /* 138 * Is this an open file structure as opposed to being String. 139 */ 140 if (iop->_flag&(_IOREAD|_IOWRT|_IORW) && (iop->_flag&_IOSTRG)==0) { 141 /* 142 * flush out any pending I/O 143 */ 144 r = fflush(iop); 145 /* 146 * tell UNIX that it can free up the file descriptor 147 */ 148 if (close(fileno(iop)) < 0) 149 r = EOF; 150 /* 151 * if we had done a malloc(3) in flsbuf or filbuf we need 152 * to give the buffer back to the system 153 */ 154 if (iop->_flag&_IOMYBUF) 155 free(iop->_base); 156 } 157 /* 158 * finially sanitize the buffer structure 159 */ 160 iop->_cnt = 0; 161 iop->_base = (char *)NULL; 162 iop->_ptr = (char *)NULL; 163 iop->_bufsiz = 0; 164 iop->_flag = 0; 165 iop->_file = 0; 166 167 return(r); 168 } 169