Function to copy a file using sendfile I've just found out there is sendfile(). In the man page of sendfile(), it says:


  sendfile() is more efficient than the combination of read(2) and write(2).


So, I wrote a function to copy a file using sendfile().

Is really my code more efficient than the combination of read(2) and write(2)?

/* leftsize is initialized with total size of source file. */
fd_src = open(src_fname, O_RDONLY);
if (fd_src&lt;0){
    printf("open failed(%s)\n", src_fname);
    return -1;
}
fd_dest = creat(dest_fname, 0666);
if (fd_dest&lt;0){
    printf("create failed(%s)\n", dest_fname);
    return -1;
}
while (leftsize &gt; 0) {
    n = sendfile(fd_dest, fd_src, NULL, max_size);
    if (n&lt;0) {
        printf("sendfile failed. ret:%d errno:%d\n", n, errno);
    }
    leftsize -= n;
}
The first paragraph of the man page says it all:


  sendfile() copies data between one file descriptor and another.
         Because this copying is done within the kernel, sendfile() is more
         efficient than the combination of read(2) and write(2), which would
         require transferring data to and from user space.


So, sendfile is quite efficient.

However, your loop may use sendfile incorrectly because you always try to transfer max_size and this could return an error (EOVERFLOW) on the last chunk of the file (i.e. you try to read more than remains in the input file).

This may work just fine if you handle the error case properly.

It also depends upon what max_size and leftsize actually are [which you didn't specify].

I'll assume that max_size is some reasonable chunk limit (e.g. max_size = 1024 * 1024;) and that leftsize is the size of the input file that comes from:

struct stat st;
fstat(fd_src,&amp;st);
leftsize = st.st_size;


So, just to be safe, here is what I'd do:

while (leftsize &gt; 0) {
    // get chunk size
    n = max_size;

    // clip transfer size to remainder of file
    if (n &gt; leftsize)
        n = leftsize;

    n = sendfile(fd_dest, fd_src, NULL, n);
    if (n&lt;0) {
        printf("sendfile failed. ret:%d errno:%d\n", n, errno);
    }

    leftsize -= n;
}