Annotation of researchv10dc/libI77/notused/flsbuf.c, revision 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.