int tio_write(TFILE *fp, const void *buf, size_t count) { size_t fr; uint8_t *tmp; size_t newsz; const uint8_t *ptr = (const uint8_t *)buf; /* keep filling the buffer until we have bufferred everything */ while (count > 0) { /* figure out free size in buffer */ fr = fp->writebuffer.size - (fp->writebuffer.start + fp->writebuffer.len); if (count <= fr) { /* the data fits in the buffer */ memcpy(fp->writebuffer.buffer + fp->writebuffer.start + fp->writebuffer.len, ptr, count); fp->writebuffer.len += count; return 0; } else if (fr > 0) { /* fill the buffer with data that will fit */ memcpy(fp->writebuffer.buffer + fp->writebuffer.start + fp->writebuffer.len, ptr, fr); fp->writebuffer.len += fr; ptr += fr; count -= fr; } /* try to flush some of the data that is in the buffer */ if (tio_flush_nonblock(fp)) return -1; /* if we have room now, try again */ if (fp->writebuffer.size > (fp->writebuffer.start + fp->writebuffer.len)) continue; /* try to grow the buffer */ if (fp->writebuffer.size < fp->writebuffer.maxsize) { newsz = fp->writebuffer.size * 2; if (newsz > fp->writebuffer.maxsize) newsz = fp->writebuffer.maxsize; tmp = realloc(fp->writebuffer.buffer, newsz); if (tmp != NULL) { fp->writebuffer.buffer = tmp; fp->writebuffer.size = newsz; continue; /* try again */ } } /* write the buffer to the stream */ if (tio_flush(fp)) return -1; } return 0; }
int tio_close(TFILE *fp) { int retv; /* write any buffered data */ retv=tio_flush(fp); #ifdef DEBUG_TIO_STATS /* dump statistics to stderr */ fprintf(stderr,"DEBUG_TIO_STATS READ=%d WRITTEN=%d\n",fp->bytesread,fp->byteswritten); #endif /* DEBUG_TIO_STATS */ /* close file descriptor */ if (close(fp->fd)) retv=-1; /* free any allocated buffers */ free(fp->readbuffer.buffer); free(fp->writebuffer.buffer); /* free the tio struct itself */ free(fp); /* return the result of the earlier operations */ return retv; }