1

I copy file on linux with sendfile. Below is the example how I use it

struct stat statBuf;
fstat(fdFrom, &statBuf);
sendfile(fd, fdFrom, 0, statBuf.st_size);
close(fd);
close(fdFrom);

Documentation to sendfile says that it may not write all bytes at once. Is the way how I use it safe? Or I should implement loop in which I check result of sendfile until will be 0?

Descriptors are from local files.

Should be target file truncated to zero before copying bytes from source file?

user1063364
  • 791
  • 6
  • 21
  • You should also check the return value from `fstat()`, otherwise `statBuf.st_size` could have garbage values. – root May 14 '23 at 18:03

1 Answers1

4

Yes, you should loop and sum up the bytes transfered until you've sent all of them. It could look something like this:

ssize_t rv;
for(off_t tot = 0; tot != statBuf.st_size; tot += (off_t)rv) {
    rv = sendfile(fd, fdFrom, NULL, statBuf.st_size - tot);
    
    if(rv == -1) {
        // handle error
    }
}

Should be target file truncated to zero before copying bytes from source file?

If you want the target file to be an exact copy, then yes, open it with the O_TRUNC flag set - or call ftruncate(fd, statBuf.st_size); after the copying has been done just in case the previous content was larger than what you just copied.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • Maybe one additional question. I must use ftruncate. I more efficient ftruncate(fd, 0); or truncate file after copying. – user1063364 May 15 '23 at 10:06
  • @user1063364 If I had to guess I would guess that _not_ truncating when opening the file and then to `ftruncate(fd, statBuf.st_size);` after the copying has been done would be the most efficient - but that's just a guess. It's better to measure to know for sure. – Ted Lyngmo May 15 '23 at 10:13