#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #define BSD_SENDFILE #endif #include #include #include #include #ifdef __linux__ #include #endif #include "iob_internal.h" int64 iob_send(int64 s,io_batch* b) { io_entry* e,* last; struct iovec* v; int64 sent; long i; long headers; #ifdef BSD_SENDFILE long trailers; #endif 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)); #ifdef BSD_SENDFILE /* 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); #else 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; } } } return sent; }