Annotation of researchv10dc/libI77/notused/flsbuf.c, revision 1.1.1.1

1.1       root        1: /*     @(#)flsbuf.c    2.8     */
                      2: /*LINTLIBRARY*/
                      3: #include <stdio.h>
                      4: #include "stdiom.h"
                      5: #include <errno.h>
                      6: 
                      7: extern void free();
                      8: extern int errno, write(), close(), isatty();
                      9: extern char *malloc();
                     10: extern FILE *_lastbuf;
                     11: #if !u370
                     12: extern unsigned char *_stdbuf[];
                     13: #endif
                     14: extern unsigned char _smbuf[][_SBFSIZ];
                     15: 
                     16: /*
                     17:  * Flush buffers on exit
                     18:  */
                     19: 
                     20: void
                     21: _cleanup()
                     22: {
                     23:        register FILE *iop;
                     24: 
                     25:        for(iop = _iob; iop < _lastbuf; iop++)
                     26:                (void) fclose(iop);
                     27: }
                     28: /*
                     29:        fclose() will flush (output) buffers for a buffered open
                     30:        FILE and then issue a system close on the _fileno.  The
                     31:        _base field will be reset to NULL for any but stdin and
                     32:        stdout, the _ptr field will be set the same as the _base
                     33:        field. The _flags and the _cnt field will be zeroed.
                     34:        If buffers had been obtained via malloc(), the space will
                     35:        be free()'d.  In case the FILE was not open, or fflush()
                     36:        or close() failed, an EOF will be returned, otherwise the
                     37:        return value is 0.
                     38:  */
                     39: 
                     40: int
                     41: fclose(iop)
                     42: register FILE *iop;
                     43: {
                     44:        register int rtn=EOF;
                     45: 
                     46:        if(iop == NULL)
                     47:                return(rtn);
                     48:        if(iop->_flag & (_IOREAD | _IOWRT | _IORW)) {
                     49:                rtn = (iop->_flag & _IONBF)? 0: fflush(iop);
                     50:                if(close(fileno(iop)) < 0) {
                     51:                        rtn = EOF;
                     52:                        errno = ENOENT;
                     53:                }
                     54:        }
                     55:        if(iop->_flag & _IOMYBUF) {
                     56:                free((char*)iop->_base);
                     57:                iop->_base = NULL;
                     58:        }
                     59:        iop->_flag = 0;
                     60:        iop->_cnt = 0;
                     61:        iop->_ptr = iop->_base;
                     62:        return(rtn);
                     63: }
                     64: 
                     65: /*
                     66:        The fflush() routine must take care because of the
                     67:        possibility for recursion. The calling program might
                     68:        do IO in an interupt catching routine that is likely
                     69:        to interupt the write() call within fflush()
                     70:  */
                     71: 
                     72: int
                     73: fflush(iop)
                     74: register FILE *iop;
                     75: {
                     76:        if (!(iop->_flag & _IOWRT)) {
                     77:                iop->_cnt = 0;
                     78:                return(0);
                     79:        }
                     80:        while(!(iop->_flag & _IONBF) && (iop->_flag & _IOWRT) &&
                     81:                        (iop->_base != NULL) && (iop->_ptr > iop->_base) )
                     82:                (void) _xflsbuf(iop);
                     83:        return(ferror(iop) ? EOF : 0);
                     84: }
                     85: 
                     86: /* The routine _flsbuf may or may not actually flush the output buffer.  If
                     87:  * the file is line-buffered, the fact that iop->_cnt has run below zero
                     88:  * is meaningless: it is always kept below zero so that invocations of putc
                     89:  * will consistently give control to _flsbuf, even if the buffer is far from
                     90:  * full.  _flsbuf, on seeing the "line-buffered" flag, determines whether the
                     91:  * buffer is actually full by comparing iop->_ptr to the end-of-buffer pointer
                     92:  * _bufend(iop).  If it is full, or if an output line is completed (with a
                     93:  * newline), the buffer is flushed.  (Note: the character argument to _flsbuf
                     94:  * is not flushed with the current buffer if the buffer is actually full--
                     95:  * it goes into the buffer after flushing.)
                     96:  */
                     97: 
                     98: int
                     99: _flsbuf(c, iop)
                    100: unsigned char c;
                    101: register FILE *iop;
                    102: {
                    103:     unsigned char c1;
                    104: 
                    105:     do {
                    106:        /* check for linebuffered with write perm, but no EOF */
                    107:        if ( (iop->_flag & (_IOLBF | _IOWRT | _IOEOF)) == (_IOLBF | _IOWRT) ) {
                    108:                if ( iop->_ptr >= _bufend(iop) )  /* if buffer full, */
                    109:                        break;              /* exit do-while, and flush buf. */
                    110:                if ( (*iop->_ptr++ = c) != '\n' )
                    111:                        return(c);
                    112:                return(_xflsbuf(iop) == EOF ? EOF : c);
                    113:        }
                    114:        /* write out an unbuffered file, if have write perm, but no EOF */
                    115:        if ( (iop->_flag & (_IONBF | _IOWRT | _IOEOF)) == (_IONBF | _IOWRT) ) {
                    116:                c1 = c;
                    117:                iop->_cnt = 0;
                    118:                if (write(fileno(iop), (char *) &c1, 1) == 1)
                    119:                        return(c);
                    120:                iop->_flag |= _IOERR;
                    121:                return(EOF);
                    122:        }
                    123:        /* The _wrtchk call is here rather than at the top of _flsbuf to re- */
                    124:        /* duce overhead for line-buffered I/O under normal circumstances.  */
                    125: 
                    126:        if (_WRTCHK(iop))                       /* is writing legitimate? */
                    127:                return(EOF);
                    128:     } while ( (iop->_flag & (_IONBF | _IOLBF)) );
                    129: 
                    130: 
                    131:     (void) _xflsbuf(iop);   /* full buffer:  flush buffer */
                    132:     (void) putc((char) c, iop);  /* then put "c" in newly emptied buf */
                    133:                        /* (which, because of signals, may NOT be empty) */
                    134:     return( ferror(iop) ? EOF : c);
                    135: }
                    136: 
                    137: /* The function _xflsbuf writes out the current contents of the output
                    138:  * buffer delimited by iop->_base and iop->_ptr.
                    139:  * iop->_cnt is reset appropriately, but its value on entry to _xflsbuf
                    140:  * is ignored.
                    141:  *
                    142:  * The following code is not strictly correct.  If a signal is raised,
                    143:  * invoking a signal-handler which generates output into the same buffer
                    144:  * being flushed, a peculiar output sequence may result (for example,
                    145:  * the output generated by the signal-handler may appear twice).  At
                    146:  * present no means has been found to guarantee correct behavior without
                    147:  * resorting to the disabling of signals, a means considered too expensive.
                    148:  * For now the code has been written with the intent of reducing the
                    149:  * probability of strange effects and, when they do occur, of confining
                    150:  * the damage.  Except under extremely pathological circumstances, this
                    151:  * code should be expected to respect buffer boundaries even in the face
                    152:  * of interrupts and other signals.
                    153:  */
                    154: 
                    155: int
                    156: _xflsbuf(iop)
                    157: register FILE *iop;
                    158: {
                    159:        register unsigned char *base;
                    160:        register int n;
                    161: 
                    162:        n = iop->_ptr - (base = iop->_base);
                    163:        iop->_ptr = base;
                    164:        iop->_cnt = (iop->_flag &(_IONBF | _IOLBF)) ? 0 : _bufsiz(iop);
                    165:        _BUFSYNC(iop);
                    166:        if (n > 0 && n != write(fileno(iop),(char*)base,(unsigned)n) )  {
                    167:                iop->_flag |= _IOERR;
                    168:                return(EOF);
                    169:        }
                    170:        return(0);
                    171: }
                    172: 
                    173: /* The function _wrtchk checks to see whether it is legitimate to write
                    174:  * to the specified device.  If it is, _wrtchk sets flags in iop->_flag for
                    175:  * writing, assures presence of a buffer, and returns 0.  If writing is not
                    176:  * legitimate, EOF is returned.
                    177:  */
                    178: 
                    179: int
                    180: _wrtchk(iop)
                    181: register FILE *iop;
                    182: {
                    183:        if ( (iop->_flag & (_IOWRT | _IOEOF)) != _IOWRT ) {
                    184:                if (!(iop->_flag & (_IOWRT | _IORW)))
                    185:                        return(EOF);  /* bogus call--read-only file */
                    186:                iop->_flag = iop->_flag & ~_IOEOF | _IOWRT; /* fix flags */
                    187:        }
                    188:        if (iop->_base == NULL)    /* this is first I/O to file--get buffer */
                    189:                _findbuf(iop);
                    190:        if (iop->_ptr == iop->_base && !(iop->_flag & (_IONBF | _IOLBF)) )  {
                    191:                iop->_cnt = _bufsiz(iop); /* first write since seek--set cnt */
                    192:                _BUFSYNC(iop);
                    193:        }
                    194:        return(0);
                    195: }
                    196: 
                    197: /*
                    198:  * _findbuf, called only when iop->_base == NULL, locates a predefined buffer
                    199:  * or allocates a buffer using malloc.  If a buffer is obtained from malloc,
                    200:  * the _IOMYBUF flag is set in iop->_flag.
                    201:  */
                    202: 
                    203: _findbuf(iop)
                    204: register FILE *iop;
                    205: {      extern int errno;
                    206:        int sverr;
                    207:        register int fno = fileno(iop); /* file number */
                    208: 
                    209:        /* allocate a small block for unbuffered, large for buffered */
                    210:        if (iop->_flag & _IONBF)  {
                    211:                _bufend(iop) = (iop->_base = _smbuf[fno]) + _SBFSIZ;
                    212:        }  else  {
                    213: #if !u370
                    214:                if (fno < 2)  /* use existing bufs for stdin, stdout */
                    215:                        _bufend(iop) = (iop->_base = _stdbuf[fno]) + BUFSIZ;
                    216:                else 
                    217: #endif
                    218:                if ((iop->_base = (unsigned char *) malloc(BUFSIZ+8)) != NULL) {
                    219:                        /* if  we got a buffer */
                    220:                        iop->_flag |= _IOMYBUF;
                    221:                        _bufend(iop) = iop->_base + BUFSIZ;
                    222:                } else
                    223:                        /* if no room for buffer, use small buffer */
                    224:                        _bufend(iop) = (iop->_base = _smbuf[fno]) + _SBFSIZ;
                    225:        }
                    226:        iop->_ptr = iop->_base;
                    227:        sverr = errno;
                    228:        if ( isatty(fno) && !(iop->_flag & _IONBF) )
                    229:                iop->_flag |= _IOLBF;
                    230:        errno = sverr;          /* isatty may set errno to ENOTTY */
                    231: }
                    232: 
                    233: /* The function _bufsync is called because interrupts and other signals
                    234:  * which occur in between the decrementing of iop->_cnt and the incrementing
                    235:  * of iop->_ptr, or in other contexts as well, may upset the synchronization
                    236:  * of iop->_cnt and iop->ptr.  If this happens, calling _bufsync should
                    237:  * resynchronize the two quantities (this is not always possible).  Resyn-
                    238:  * chronization guarantees that putc invocations will not write beyond
                    239:  * the end of the buffer.  Note that signals during _bufsync can cause
                    240:  * _bufsync to do the wrong thing, but usually with benign effects.
                    241:  */
                    242: 
                    243: _bufsync(iop)
                    244: register FILE *iop;
                    245: {
                    246:        register int spaceleft;
                    247: 
                    248:        if ((spaceleft = _bufend(iop) - iop->_ptr) < 0)
                    249:                iop->_ptr = _bufend(iop);
                    250:        else if (spaceleft < iop->_cnt)
                    251:                iop->_cnt = spaceleft;
                    252: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.