extern int buffer_flush(buffer* b) { register size_t p; register ssize_t r; if(!(p = b->p)) return 0; /* buffer already empty */ b->p = 0; r = buffer_stubborn(b->op, b->fd, b->x, p, b); if(r > 0) r = 0; return (int)r; }
ssize_t buffer_putflush(buffer* b, const char* x, size_t len) { /* Since we know we are going to flush anyway, let's see if we can * optimize a bit */ if(!b->p) /* if the buffer is empty, just call buffer_stubborn directly */ return buffer_stubborn(b->op, b->fd, x, len, b); #if !WINDOWS_NATIVE if(b->op == (buffer_op_fn*)&write) { struct iovec v[2]; ssize_t w; size_t cl = b->p + len; v[0].iov_base = b->x; v[0].iov_len = b->p; v[1].iov_base = (char*)x; v[1].iov_len = len; while((w = writev(b->fd, v, 2)) < 0) { if(errno == EINTR) continue; return -1; } if(__unlikely((size_t)w != cl)) { /* partial write. ugh. */ if((size_t)w < v[0].iov_len) { if(buffer_stubborn(b->op, b->fd, v[0].iov_base + w, v[0].iov_len - w, b) || buffer_stubborn(b->op, b->fd, v[1].iov_base, v[0].iov_len, b)) return -1; } else { w -= v[0].iov_len; return buffer_stubborn(b->op, b->fd, v[1].iov_base + w, v[1].iov_len - w, b); } } b->p = 0; return 0; } #endif if(buffer_put(b, x, len) < 0) return -1; if(buffer_flush(b) < 0) return -1; return 0; }
int buffer_put(buffer* b, const char* buf, size_t len) { if(len > b->a - b->p) { /* doesn't fit */ if(buffer_flush(b) == -1) return -1; if(len > b->a) { if(buffer_stubborn(b->op, b->fd, buf, len, b) < 0) return -1; return 0; } } byte_copy(b->x + b->p, len, buf); b->p += len; return 0; }
extern int buffer_flush(buffer* b) { register int p; if (!(p=b->p)) return 0; /* buffer already empty */ b->p=0; return buffer_stubborn(b->op,b->fd,b->x,p); }