diff --git a/io/iob_send.c b/io/iob_send.c index 42f48d7..a8f1541 100644 --- a/io/iob_send.c +++ b/io/iob_send.c @@ -24,62 +24,67 @@ int64 iob_send(int64 s,io_batch* b) { if (b->bytesleft==0) return 0; last=array_start(&b->b)+array_bytes(&b->b); - if (!(e=array_get(&b->b,sizeof(io_entry),b->next))) - return -1; /* can't happen error */ v=alloca(b->bufs*sizeof(struct iovec)); + for (;;) { + if (!(e=array_get(&b->b,sizeof(io_entry),b->next))) + return -1; /* can't happen error */ #ifdef BSD_SENDFILE - /* BSD sendfile can send headers and trailers. If we run on BSD, we - * should try to exploit this. */ - headers=trailers=0; + /* BSD sendfile can send headers and trailers. If we run on BSD, we + * should try to exploit this. */ + headers=trailers=0; #endif - for (i=0; e+ibytesleft; - else if (r==-1 && errno==EAGAIN) - sent=sbytes; - else - sent=-1; - } else - sent=writev(s,v,headers); + headers=i; +#ifdef BSD_SENDFILE + if (e[i].type==FROMFILE) { + off_t sbytes; + struct sf_hdtr hdr; + int r; + for (++i; e+ibytesleft; + else if (r==-1 && errno==EAGAIN) + sent=sbytes; + else + sent=-1; + } else + sent=writev(s,v,headers); #else - if (headers) - sent=writev(s,v,headers); - else - sent=io_sendfile(s,e->fd,e->offset,e->n); + if (headers) + sent=writev(s,v,headers); + else + sent=io_sendfile(s,e->fd,e->offset,e->n); #endif - if (sent==b->bytesleft) - b->bytesleft=0; - else if (sent>0) { - int64 rest=sent; - b->bytesleft-=rest; - for (i=0; e+inext; - } else { - e[i].offset+=rest; - break; + if (sent==b->bytesleft) { + b->bytesleft=0; + break; + } else if (sent>0) { + int64 rest=sent; + b->bytesleft-=rest; + for (i=0; e+inext; + if (!rest) break; + } else { + e[i].offset+=rest; + goto abort; + } } - } + } else break; } +abort: return sent; }