Skip to content
Snippets Groups Projects
Commit cefb204e authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

Bring some sanity to sendfilesocket()

Not that there's any need to, it appears that it was written for
the web server, then discarded for that purpose and now is only
called from the JS Socket.sendfile() method, which always passes
NULL and 0 for the last two parameters, and has a copy/pasted
implementation for TLS sockets.  The only consumer of that in
the tree appears to be gopher_service.js.

It was apparently to use as a wrapper for the high-performance
FreeBSD sendfile(), but that code behaved differently than all
the other platforms, and was disabled (behind USE_SENDFILE, which
isn't defined anywhere).

This should really just be folded into either js_socket_sendfilesocket()
or js_sendfile() with the extra knobs broken off and all the TODO
comments I'm adding here addressed.

Though, since Socket.sendfile() returns a bool where true indicates
that either the size of the file at the start of the function
was sent, or an EOF was reached, and false indicates that
"something else happened", some of the TODO comments don't really
need to be addressed.

Basically, this is a crap function and it's only used by an even
more crap JS wrapper, it should be tucked into a backward
compatibility function, removed from the JSDocs, and forgotten
about.

If Coverity keeps complaining about this, I'll wait until after
the next release and drag this out back and shoot it.  Otherwise,
I'll just forget it ever existed.
parent 5178675c
Branches
Tags
No related merge requests found
......@@ -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);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment