diff --git a/src/xpdev/sockwrap.c b/src/xpdev/sockwrap.c index ed4bb4d8d112817fe2117458651c714ee0642d6d..5e0e527f052bda6f658271a66c421d4869be378c 100644 --- a/src/xpdev/sockwrap.c +++ b/src/xpdev/sockwrap.c @@ -153,67 +153,57 @@ socket_option_t* getSocketOptionList(void) return(socket_options); } +// TODO: Only called with *offset == NULL and count == 0... off_t sendfilesocket(int sock, int file, off_t *offset, off_t count) { char buf[1024*16]; off_t len; - ssize_t rd; - ssize_t wr=0; off_t total=0; - ssize_t i; -/* sendfile() on Linux may or may not work with non-blocking sockets ToDo */ - len=filelength(file); + // TODO: Race condition here... length may change. + // But note that js_socket_sendfilesocket() reimplements all of this + // for encrypted sockets. + len = filelength(file); if(offset!=NULL) if(lseek(file,*offset,SEEK_SET)<0) return(-1); - if(count<1 || count>len) { - count=len; - count-=tell(file); /* don't try to read beyond EOF */ + if (count < 1 || count > len) { + count = len; + count -= tell(file); /* don't try to read beyond EOF (why not? --- Deuce) */ } -#if USE_SENDFILE - while((i=sendfile(file,sock,(offset==NULL?0:*offset)+total,count-total,NULL,&wr,0))==-1 && errno==EAGAIN) { - total+=wr; - SLEEP(1); - } - if(i==0) - return(count); -#endif - if(count<0) { - errno=EINVAL; + if (count < 0) { + errno = EINVAL; return(-1); } - while(total<count) { - rd = read(file, buf, sizeof(buf)); - if (rd < 0) + while (total < count) { + ssize_t rd = read(file, buf, sizeof(buf)); + if (rd < 0) // Error return(-1); - if (rd == 0) + if (rd == 0) // EOF break; - for (i = wr = 0; i < rd; i += wr) { - wr = sendsocket(sock,buf+i,rd-i); + ssize_t sent = 0; + while (sent < rd) { + ssize_t wr = sendsocket(sock, buf + sent, rd - sent); if (wr > 0) { - if ((rd - i) < wr) - wr = rd - i; - continue; + sent += wr; } - if (wr == SOCKET_ERROR && SOCKET_ERRNO == EWOULDBLOCK) { - wr = 0; + else if (wr == SOCKET_ERROR && SOCKET_ERRNO == EWOULDBLOCK) { SLEEP(1); - continue; } - return(wr); + else { + // TODO: This is sketchy to return 0 on write failure + return(wr); + } } - if(i!=rd) - return(-1); - total+=rd; + total += rd; } - if(offset!=NULL) - (*offset)+=total; + if (offset != NULL) + (*offset) += total; return(total); }