Annotation of mstools/posix/samples/psxarc/buf.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3:        This file contains stuff for buffering input and output.  We use
        !             4:        this buffering to allow us to deal with end-of-media conditions
        !             5:        on input or output streams.
        !             6: 
        !             7:        Warning: at this time, these buffers don't get flushed automatically
        !             8:                on exit; bclose() must be called.
        !             9: 
        !            10: --*/
        !            11: 
        !            12: #include <stdio.h>
        !            13: #include <fcntl.h>
        !            14: #include <errno.h>
        !            15: #include <stdlib.h>
        !            16: #include <unistd.h>
        !            17: #include "buf.h"
        !            18: 
        !            19: extern char *progname;
        !            20: 
        !            21: static PBUF balloc(void);
        !            22: static void bfree(PBUF);
        !            23: 
        !            24: //
        !            25: // Create a new buffer and associate it with a file.  If the file
        !            26: // can't be opened, return NULL.
        !            27: //
        !            28: PBUF
        !            29: bopen(const char *file, int mode)
        !            30: {
        !            31:        PBUF pb;
        !            32:        
        !            33:        pb = balloc();
        !            34: 
        !            35:        if (-1 == (pb->fd = open(file, mode, 0666))) {
        !            36:                fprintf(stderr, "%s: open: ", progname);
        !            37:                perror(file);
        !            38:                exit(1);
        !            39:        }
        !            40:        pb->mode = mode;
        !            41:        pb->count = 0;
        !            42:        pb->offset = 0;
        !            43: 
        !            44:        return pb;
        !            45: }
        !            46: 
        !            47: //
        !            48: // Same as bopen, but from a file descriptor.
        !            49: //
        !            50: PBUF
        !            51: bfdopen(int fd, int mode)
        !            52: {
        !            53:        PBUF pb;
        !            54: 
        !            55:        pb = balloc();
        !            56: 
        !            57:        pb->fd = fd;
        !            58:        pb->mode = mode;
        !            59:        pb->count = 0;
        !            60:        pb->offset = 0;
        !            61: 
        !            62:        return pb;
        !            63: }
        !            64: 
        !            65: void
        !            66: bclose(PBUF pb)
        !            67: {
        !            68:        if (pb->mode & O_WRONLY && pb->offset != 0) {
        !            69:                bflush(pb);
        !            70:        }
        !            71:        (void)close(pb->fd);
        !            72:        bfree(pb);
        !            73: }
        !            74: 
        !            75: int
        !            76: bgetc(PBUF pb)
        !            77: {
        !            78:        if (pb->offset == pb->count) {
        !            79:                bfill(pb);
        !            80:        }
        !            81: 
        !            82:        // We don't worry about reaching EOF here; the caller has to
        !            83:        // know how many bytes are available and read only that many,
        !            84: 
        !            85:        return pb->data[pb->offset++];
        !            86: }
        !            87: 
        !            88: void
        !            89: bputc(PBUF pb, int c)
        !            90: {
        !            91:        pb->data[pb->offset++] = (char)c;
        !            92:        if (sizeof(pb->data) == ++pb->count) {
        !            93:                bflush(pb);
        !            94:        }
        !            95: }
        !            96: 
        !            97: //
        !            98: // Set a buffer back to the beginning; that is, the next character
        !            99: // read will be the first one.  Could be used on write buffers as well,
        !           100: // but not as likely.
        !           101: //
        !           102: void
        !           103: brewind(PBUF pb)
        !           104: {
        !           105:        pb->offset = 0;
        !           106: }
        !           107: 
        !           108: //
        !           109: // balloc --
        !           110: //     Allocate and initialize a buffer.  A pointer to the new buffer
        !           111: //     is returned.  We set fd to -1 to help find out if people are
        !           112: //     writing to a buffer before opening it.
        !           113: //
        !           114: static PBUF
        !           115: balloc()
        !           116: {
        !           117:        PBUF pb;
        !           118: 
        !           119:        if (NULL == (pb = malloc(sizeof(BUF)))) {
        !           120:                fprintf(stderr, "%s: malloc: virtual memory exhausted\n",
        !           121:                        progname);
        !           122:                exit(4);
        !           123:        }
        !           124:        return pb;
        !           125: }
        !           126: 
        !           127: static void
        !           128: bfree(PBUF pb)
        !           129: {
        !           130:        free(pb);
        !           131: }
        !           132: 
        !           133: //
        !           134: // write the contents of a buffer, dealing with end-of-media, if necessary.
        !           135: //
        !           136: void
        !           137: bflush(PBUF pb)
        !           138: {
        !           139:        int nbyte;
        !           140: 
        !           141:        nbyte = write(pb->fd, pb->data, sizeof(pb->data));
        !           142:        if (-1 == nbyte) {
        !           143:                if (ENOSPC == errno) {
        !           144:                        // end-of-media; do something about it.
        !           145:                } else {
        !           146:                        fprintf(stderr, "%s: ", progname);
        !           147:                        perror("write");
        !           148:                        exit(1);
        !           149:                }
        !           150:        }
        !           151:        pb->count = 0;
        !           152:        pb->offset = 0;
        !           153: }
        !           154: 
        !           155: //
        !           156: // fill a buffer with data, dealing with end-of-media, if necessary.
        !           157: //
        !           158: void
        !           159: bfill(PBUF pb)
        !           160: {
        !           161:        int nbyte;
        !           162: 
        !           163:        nbyte = read(pb->fd, pb->data, sizeof(pb->data));
        !           164:        if (-1 == nbyte) {
        !           165:                fprintf(stderr, "%s: ", progname);
        !           166:                perror("read");
        !           167:                exit(2);
        !           168:        }
        !           169:        if (0 == nbyte) {
        !           170:                // we have reached the end of file.  Give user opportunity
        !           171:                // to replace the media, and fill the rest of this
        !           172:                // buffer XXX.mjb
        !           173:                return;
        !           174:        }
        !           175:        pb->count = nbyte;
        !           176:        pb->offset = 0;
        !           177: }

unix.superglobalmegacorp.com

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