Annotation of mstools/posix/samples/psxarc/buf.c, revision 1.1.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.