https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=288985

            Bug ID: 288985
           Summary: [regression 14.2] copy_file_range fails to update
                    inoffp and outoffp
           Product: Base System
           Version: 14.3-RELEASE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: [email protected]
          Reporter: [email protected]

Ref: https://bugreports.qt.io/browse/QTBUG-138570

Testcase:
#include <sys/types.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    if (argc < 2) {
        puts("usage: copyfilerangetest src dst");
        return 0;
    }

    int src = open(argv[1], O_RDONLY);
    int dst = open(argv[2], O_WRONLY | O_CREAT, 0777);
    off_t srcoffset = 0;
    off_t dstoffset = 0;
    ssize_t copied;
    do {
        copied = copy_file_range(src, &srcoffset, dst, &dstoffset, SSIZE_MAX,
0);
    } while (copied < 0);
    printf("copied %zd bytes (srcoffset now %ld dstoffset now %ld)\n",
           copied, srcoffset, dstoffset);
}

Execute:
 echo hello > foo
 ./a.out foo bar

If you run this on 14.2, it will say "copied 6 bytes (srcoffset now 6 dstoffset
now 6)". If you run this on 14.3, it will say "srcoffset now 0 dstoffset now
0".

This broke the Qt implementation which relied on a similar loop to the above to
copy a full file, if interruptions might happen:

     do {
         copied = ::copy_file_range(srcfd, &srcoffset, dstfd, &dstoffset,
SSIZE_MAX, 0);
     } while (copied > 0 || (copied < 0 && errno == EINTR));

Because srcoffset = 0 on return, we ended up copying the same bytes over and
over again.

-- 
You are receiving this mail because:
You are the assignee for the bug.

Reply via email to