Question

Reading through the man page of the Linux system call sendfile, I am wondering whether it is possible for the calling program to know when in_fd is at EOF. Presumably, this could be signaled by a return value of 0, but this leads to the question of what a return value of 0 actually means. If sendfile is like write, then a return value of 0 would just mean that 0 bytes were copied. But, if sendfile is like read, then a return value of 0 would mean EOF. Must one know in advance how many bytes that are to be copied from in_fd to out_fd in order to use sendfile? What does it mean when sendfile returns 0?

Was it helpful?

Solution

I don't think there is any direct way to know that but it shouldn't really matter. Normally you would find the input file size via stat/fstat and use that to count out your transfer. The socket end isn't going to matter to you.

The only situation this should be problematic is if you want to transfer a file that is growing or shrinking. Given that the input file has to be mmap-ed, and the bad things that can happen (without some clever code) with mmap in those situations you should probably just not employ sendfile for those cases.

OTHER TIPS

you can use offset parameter for read count.

According to Man page

If offset is not NULL, then it points to a variable holding the file offset from which sendfile() will start reading data from in_fd. When sendfile() returns, this variable will be set to the offset of the byte following the last byte that was read. If offset is not NULL, then sendfile() does not modify the current file offset of in_fd; otherwise the current file offset is adjusted to reflect the number of bytes read from in_fd.

count is the number of bytes to copy between the file descriptors.

RETURN VALUE If the transfer was successful, the number of bytes written to out_fd is returned. On error, -1 is returned, and errno is set appropriately.

and yes that means return value 0 means no data copied to write socket.

You can assume EOF has been reached when then number of bytes sent is 0:

sent = sendfile(out_fd, in_fd, &offset, nbytes);
if (sent == 0) {
    // EOF
    ...
}

This assumption works also in case of non-blocking sockets.

in my case, encounter the file be truncate by rsync, app use sendfile to transmit file in the same time. I find the app eat cpu 100% in the condition, I fix my code refer the follow article , the question disappear. http://www.linuxjournal.com/article/6345

the point is use F_SETLEASE get the file leases for your app.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top