Files
velzieandClaude Opus 4.8 07c702f784 sendfile, copy_file_range: in-kernel fd-to-fd copies, not ENOSYS
A syscall probe found both unimplemented. They are how a static file server
sends a file to a socket without bouncing every byte through userspace, and how
node's fs.copyFile takes its fast path -- leaving them ENOSYS forces the slow
read/write loop and, for sendfile, can defeat a server's whole design.

Both share one helper that copies through a single kernel buffer:
  - The offset-pointer forms (sendfile with a non-null offset, copy_file_range's
    off_in/off_out) read/write at an absolute offset without moving the
    descriptor's own position, then advance the caller's pointer -- so a server
    serves one open file to many clients without seeking.
  - The positional-less form uses and advances the descriptor's position. If the
    output takes fewer bytes than were read, the input is rewound by the
    shortfall so nothing is silently dropped.
  - One call moves at most one buffer (16 MiB cap), as Linux does; callers loop.
  - copy_file_range rejects non-zero flags with EINVAL (reserved).

Integration test covers sendfile no-offset, sendfile with an offset pointer, and
copy_file_range with both offsets -- byte-identical to QEMU.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_019b4VWMhJUWoGKQh4EeFfPm
2026-08-13 07:39:56 -04:00

59 lines
1.8 KiB
C

/* sendfile and copy_file_range: in-kernel descriptor-to-descriptor copies that
* static file servers and node's fs fast paths use. Exercises the no-offset
* form (advances the input position), the offset-pointer form (leaves it, bumps
* the pointer), and copy_file_range with both offsets. Deterministic -> QEMU
* is the oracle. */
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/sendfile.h>
#include <sys/syscall.h>
#include <unistd.h>
static const char *rd(const char *p) {
static char b[128];
int f = open(p, O_RDONLY);
if (f < 0) return "<none>";
int n = read(f, b, 127);
close(f);
if (n < 0) n = 0;
b[n] = 0;
return b;
}
int main(void) {
chdir("/tmp");
unlink("src"); unlink("dst"); unlink("dst2"); unlink("dst3");
int s = open("src", O_CREAT | O_WRONLY | O_TRUNC, 0644);
write(s, "Hello, sendfile world!", 22);
close(s);
int in = open("src", O_RDONLY);
int out = open("dst", O_CREAT | O_WRONLY | O_TRUNC, 0644);
ssize_t r = sendfile(out, in, NULL, 22);
close(in);
close(out);
printf("sendfile-noff ret=%zd dst=%s\n", r, rd("dst"));
in = open("src", O_RDONLY);
out = open("dst2", O_CREAT | O_WRONLY | O_TRUNC, 0644);
off_t off = 7;
r = sendfile(out, in, &off, 15);
close(in);
close(out);
printf("sendfile-off ret=%zd off=%ld dst2=%s\n", r, (long)off, rd("dst2"));
in = open("src", O_RDONLY);
out = open("dst3", O_CREAT | O_WRONLY | O_TRUNC, 0644);
loff_t io = 0, oo = 0;
r = syscall(SYS_copy_file_range, in, &io, out, &oo, 5, 0);
close(in);
close(out);
printf("cfr ret=%zd io=%ld oo=%ld dst3=%s\n", r, (long)io, (long)oo, rd("dst3"));
unlink("src"); unlink("dst"); unlink("dst2"); unlink("dst3");
printf("sendfile ok\n");
return 0;
}