Annotation of libaitio/src/bufio.c, revision 1.2

1.2     ! misho       1: #include "global.h"
        !             2: 
        !             3: 
        !             4: static void
        !             5: unmap_cf(struct tagBufIO *buf)
        !             6: {
        !             7:        if (buf)
        !             8:                munmap(buf->buf_base, buf->buf_size);
        !             9: }
        !            10: 
        !            11: static int
        !            12: cf_(struct tagBufIO *buf)
        !            13: {
        !            14:        if (!buf) {
        !            15:                io_SetErr(EINVAL, "Invalid arguments ...");
        !            16:                return -1;
        !            17:        }
        !            18: 
        !            19:        if (buf->buf_mode == BUFIO_MODE_INFINIT)
        !            20:                free(buf->buf_base);
        !            21:        else if (buf->buf_unmap)
        !            22:                buf->buf_unmap(buf);
        !            23: 
        !            24:        free(buf);
        !            25:        return 0;
        !            26: }
        !            27: 
        !            28: static fpos_t
        !            29: sf_lim(struct tagBufIO *buf, fpos_t pos, int w)
        !            30: {
        !            31:        if (!buf)
        !            32:                goto err;
        !            33: 
        !            34:        switch (w) {
        !            35:                case SEEK_SET:
        !            36:                        if (buf->buf_size < pos || pos < 0)
        !            37:                                goto err;
        !            38:                        buf->buf_offset = pos;
        !            39:                        break;
        !            40:                case SEEK_CUR:
        !            41:                        if (buf->buf_size < (buf->buf_offset + pos) || (buf->buf_offset + pos) < 0)
        !            42:                                goto err;
        !            43:                        buf->buf_offset += pos;
        !            44:                        break;
        !            45:                case SEEK_END:
        !            46:                        if (buf->buf_size < (buf->buf_size + pos) || (buf->buf_size + pos) < 0)
        !            47:                                goto err;
        !            48:                        buf->buf_offset = buf->buf_size + pos;
        !            49:                        break;
        !            50:                default:
        !            51:                        goto err;
        !            52:        }
        !            53: 
        !            54:        return buf->buf_offset;
        !            55: err:
        !            56:        io_SetErr(EINVAL, "Invalid arguments ...");
        !            57:        return -1;
        !            58: }
        !            59: 
        !            60: static int
        !            61: rf_lim(struct tagBufIO *buf, char *dat, int siz)
        !            62: {
        !            63:        if (!buf || !dat) {
        !            64:                io_SetErr(EINVAL, "Invalid arguments ...");
        !            65:                return -1;
        !            66:        }
        !            67: 
        !            68:        if (buf->buf_offset + siz > buf->buf_size)
        !            69:                siz = buf->buf_size - buf->buf_offset;
        !            70: 
        !            71:        memcpy(dat, buf->buf_base + buf->buf_offset, siz);
        !            72:        buf->buf_offset += siz;
        !            73:        return siz;
        !            74: }
        !            75: 
        !            76: static int
        !            77: wf_lim(struct tagBufIO *buf, const char *dat, int siz)
        !            78: {
        !            79:        if (!buf || !dat) {
        !            80:                io_SetErr(EINVAL, "Invalid arguments ...");
        !            81:                return -1;
        !            82:        }
        !            83: 
        !            84:        if (buf->buf_offset + siz > buf->buf_size)
        !            85:                siz = buf->buf_size - buf->buf_offset;
        !            86: 
        !            87:        memcpy(buf->buf_base + buf->buf_offset, dat, siz);
        !            88:        buf->buf_offset += siz;
        !            89:        return siz;
        !            90: }
        !            91: 
        !            92: static fpos_t
        !            93: sf_inf(struct tagBufIO *buf, fpos_t pos, int w)
        !            94: {
        !            95:        void *b;
        !            96: 
        !            97:        if (!buf)
        !            98:                goto err;
        !            99: 
        !           100:        switch (w) {
        !           101:                case SEEK_SET:
        !           102:                        if (pos < 0)
        !           103:                                goto err;
        !           104:                        if (buf->buf_size < pos) {
        !           105:                                b = realloc(buf->buf_base, pos);
        !           106:                                if (!b) {
        !           107:                                        LOGERR;
        !           108:                                        return -1;
        !           109:                                } else {
        !           110:                                        buf->buf_base = b;
        !           111:                                        memset(buf->buf_base + buf->buf_size, 0, pos - buf->buf_size);
        !           112:                                        buf->buf_size = pos;
        !           113:                                }
        !           114:                        }
        !           115:                        buf->buf_offset = pos;
        !           116:                        break;
        !           117:                case SEEK_CUR:
        !           118:                        if ((buf->buf_offset + pos) < 0)
        !           119:                                goto err;
        !           120:                        if (buf->buf_size < (buf->buf_offset + pos)) {
        !           121:                                b = realloc(buf->buf_base, buf->buf_offset + pos);
        !           122:                                if (!b) {
        !           123:                                        LOGERR;
        !           124:                                        return -1;
        !           125:                                } else {
        !           126:                                        buf->buf_base = b;
        !           127:                                        memset(buf->buf_base + buf->buf_size, 0, 
        !           128:                                                        buf->buf_offset + pos - buf->buf_size);
        !           129:                                        buf->buf_size = buf->buf_offset + pos;
        !           130:                                }
        !           131:                        }
        !           132:                        buf->buf_offset += pos;
        !           133:                        break;
        !           134:                case SEEK_END:
        !           135:                        if ((buf->buf_size + pos) < 0)
        !           136:                                goto err;
        !           137:                        if (buf->buf_size < (buf->buf_size + pos)) {
        !           138:                                b = realloc(buf->buf_base, buf->buf_size + pos);
        !           139:                                if (!b) {
        !           140:                                        LOGERR;
        !           141:                                        return -1;
        !           142:                                } else {
        !           143:                                        buf->buf_base = b;
        !           144:                                        memset(buf->buf_base + buf->buf_size, 0, pos);
        !           145:                                        buf->buf_size += pos;
        !           146:                                        buf->buf_offset = buf->buf_size;
        !           147:                                }
        !           148:                        } else
        !           149:                                buf->buf_offset = buf->buf_size + pos;
        !           150:                        break;
        !           151:                default:
        !           152:                        goto err;
        !           153:        }
        !           154: 
        !           155:        return buf->buf_offset;
        !           156: err:
        !           157:        io_SetErr(EINVAL, "Invalid arguments ...");
        !           158:        return -1;
        !           159: }
        !           160: 
        !           161: static int
        !           162: wf_inf(struct tagBufIO *buf, const char *dat, int siz)
        !           163: {
        !           164:        void *b;
        !           165: 
        !           166:        if (!buf || !dat) {
        !           167:                io_SetErr(EINVAL, "Invalid arguments ...");
        !           168:                return -1;
        !           169:        }
        !           170: 
        !           171:        if (buf->buf_offset + siz > buf->buf_size) {
        !           172:                b = realloc(buf->buf_base, buf->buf_offset + siz);
        !           173:                if (!b) {
        !           174:                        LOGERR;
        !           175:                        return -1;
        !           176:                } else {
        !           177:                        buf->buf_base = b;
        !           178:                        memset(buf->buf_base + buf->buf_size, 0, 
        !           179:                                        buf->buf_offset + siz - buf->buf_size);
        !           180:                        buf->buf_size = buf->buf_offset + siz;
        !           181:                }
        !           182:        }
        !           183: 
        !           184:        memcpy(buf->buf_base + buf->buf_offset, dat, siz);
        !           185:        buf->buf_offset += siz;
        !           186:        return siz;
        !           187: }
        !           188: 
        !           189: 
        !           190: /*
        !           191:  * io_fmemopen() File buffered stream operations over memory block
        !           192:  *
        !           193:  * @base = Base address of memory block, if =NULL Infinit length(auto-grow)
        !           194:  * @basesize = Size of memory block
        !           195:  * return: NULL error or !=NULL Opened file resource
        !           196:  */
        !           197: FILE *
        !           198: io_fmemopen(void ** __restrict base, off_t basesize)
        !           199: {
        !           200:        FILE *f = NULL;
        !           201:        struct tagBufIO *buf;
        !           202: 
        !           203:        if (!base) {
        !           204:                io_SetErr(EINVAL, "Invalid base argument ...");
        !           205:                return NULL;
        !           206:        }
        !           207: 
        !           208:        buf = malloc(sizeof(struct tagBufIO));
        !           209:        if (!buf) {
        !           210:                LOGERR;
        !           211:                return NULL;
        !           212:        } else
        !           213:                memset(buf, 0, sizeof(struct tagBufIO));
        !           214: 
        !           215:        if (!*base) {
        !           216:                *base = malloc(basesize);
        !           217:                if (!*base) {
        !           218:                        LOGERR;
        !           219:                        free(buf);
        !           220:                        return NULL;
        !           221:                } else
        !           222:                        memset(*base, 0, basesize);
        !           223: 
        !           224:                buf->buf_mode = BUFIO_MODE_INFINIT;
        !           225:        } else
        !           226:                buf->buf_mode = BUFIO_MODE_LIMIT;
        !           227: 
        !           228:        buf->buf_base = *base;
        !           229:        buf->buf_size = basesize;
        !           230: 
        !           231:        if (buf->buf_mode == BUFIO_MODE_INFINIT)
        !           232:                f = funopen(buf, (int (*)(void *, char *, int)) rf_lim, 
        !           233:                                (int (*)(void *, char const *, int)) wf_inf, 
        !           234:                                (fpos_t (*)(void *, fpos_t, int)) sf_inf, 
        !           235:                                (int (*)(void *)) cf_);
        !           236:        else
        !           237:                f = funopen(buf, (int (*)(void *, char *, int)) rf_lim, 
        !           238:                                (int (*)(void *, char const *, int)) wf_lim, 
        !           239:                                (fpos_t (*)(void *, fpos_t, int)) sf_lim, 
        !           240:                                (int (*)(void *)) cf_);
        !           241:        if (!f) {
        !           242:                LOGERR;
        !           243:                if (buf->buf_mode == BUFIO_MODE_INFINIT) {
        !           244:                        free(*base);
        !           245:                        *base = NULL;
        !           246:                }
        !           247:                free(buf);
        !           248:                return NULL;
        !           249:        }
        !           250: 
        !           251:        return f;
        !           252: }
        !           253: 
        !           254: /*
        !           255:  * io_fmapopen() File buffered stream operations over MMAP block
        !           256:  *
        !           257:  * @csFile = Filename for MMAP, if =NULL private MMAP block
        !           258:  * @mode = File open mode
        !           259:  * @perm = If file not exists will be created with this access permissions
        !           260:  * @prot = MMAP protection
        !           261:  * @flags = MMAP mode flags
        !           262:  * @offset = Map from file offset, if csFile==NULL then this is size of MMAP private block
        !           263:  * return: NULL error or !=NULL Opened file resource
        !           264:  */
        !           265: FILE *
        !           266: io_fmapopen(const char *csFile, int mode, int perm, int prot, int flags, off_t offset)
        !           267: {
        !           268:        FILE *f;
        !           269:        struct tagBufIO *buf;
        !           270:        void *base;
        !           271:        off_t basesize;
        !           272:        int fd = -1;
        !           273: 
        !           274:        if (csFile) {
        !           275:                fd = open(csFile, mode, perm);
        !           276:                if (fd == -1) {
        !           277:                        LOGERR;
        !           278:                        return NULL;
        !           279:                }
        !           280:                basesize = lseek(fd, 0, SEEK_END);
        !           281:                if (basesize == -1) {
        !           282:                        LOGERR;
        !           283:                        close(fd);
        !           284:                        return NULL;
        !           285:                } else
        !           286:                        lseek(fd, 0, SEEK_SET);
        !           287: 
        !           288:                base = mmap(NULL, basesize, prot, flags | MAP_FILE, fd, offset);
        !           289:                if (base == MAP_FAILED) {
        !           290:                        LOGERR;
        !           291:                        close(fd);
        !           292:                        return NULL;
        !           293:                } else
        !           294:                        close(fd);
        !           295:        } else if (offset) {
        !           296:                basesize = offset;
        !           297:                base = mmap(NULL, basesize, prot, MAP_ANON, -1, 0);
        !           298:                if (base == MAP_FAILED) {
        !           299:                        LOGERR;
        !           300:                        return NULL;
        !           301:                }
        !           302:        } else {
        !           303:                io_SetErr(EINVAL, "Invalid base argument ...");
        !           304:                return NULL;
        !           305:        }
        !           306: 
        !           307: 
        !           308:        buf = malloc(sizeof(struct tagBufIO));
        !           309:        if (!buf) {
        !           310:                LOGERR;
        !           311:                munmap(base, basesize);
        !           312:                return NULL;
        !           313:        } else
        !           314:                memset(buf, 0, sizeof(struct tagBufIO));
        !           315: 
        !           316:        buf->buf_mode = BUFIO_MODE_LIMIT;
        !           317:        buf->buf_base = base;
        !           318:        buf->buf_size = basesize;
        !           319:        buf->buf_unmap = unmap_cf;
        !           320: 
        !           321:        f = funopen(buf, (int (*)(void *, char *, int)) rf_lim, 
        !           322:                        (int (*)(void *, char const *, int)) wf_lim, 
        !           323:                        (fpos_t (*)(void *, fpos_t, int)) sf_lim, 
        !           324:                        (int (*)(void *)) cf_);
        !           325:        if (!f) {
        !           326:                LOGERR;
        !           327:                free(buf);
        !           328:                munmap(base, basesize);
        !           329:                return NULL;
        !           330:        }
        !           331: 
        !           332:        return f;
        !           333: }
        !           334: 
        !           335: /*
        !           336:  * io_dumbFile() Create empry or dumb file with fixed size
        !           337:  *
        !           338:  * @csFile = Filename for create
        !           339:  * @mode = File access permissions
        !           340:  * @size = File size
        !           341:  * return: -1 error or open file handle
        !           342:  */
        !           343: int
        !           344: io_dumbFile(const char *csFile, int mode, off_t size)
        !           345: {
        !           346:        int fd;
        !           347: 
        !           348:        fd = open(csFile, O_RDWR | O_CREAT, mode);
        !           349:        if (fd == -1) {
        !           350:                LOGERR;
        !           351:                return -1;
        !           352:        }
        !           353: 
        !           354:        if (lseek(fd, size - 1, SEEK_SET) == -1)
        !           355:                goto err;
        !           356:        if (write(fd, "", 1) != 1)
        !           357:                goto err;
        !           358:        else
        !           359:                lseek(fd, 0, SEEK_SET);
        !           360: 
        !           361:        return fd;
        !           362: err:
        !           363:        LOGERR;
        !           364:        close(fd);
        !           365:        return -1;
        !           366: }
        !           367: 
        !           368: /*
        !           369:  * io_fd2buf() Convert open file handle to buffered file I/O
        !           370:  *
        !           371:  * @fd = File handle
        !           372:  * @mode = Permissions for new buffered file I/O
        !           373:  * return: NULL error or open buffered file
        !           374:  */
        !           375: inline FILE *
        !           376: io_fd2buf(int fd, const char *mode)
        !           377: {
        !           378:        FILE *f;
        !           379: 
        !           380:        f = fdopen(fd, mode);
        !           381:        if (!f)
        !           382:                LOGERR;
        !           383: 
        !           384:        return f;
        !           385: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>