copy_file_range.2: Document glibc wrapper instead of kernel syscall

Glibc uses 'off64_t' instead of 'loff_t'.

......

Glibc prototype:

$ syscall='copy_file_range';
$ ret='ssize_t';
$ find glibc/ -type f -name '*.h' \
  |xargs pcregrep -Mn "(?s)^[\w\s]*${ret}\s*${syscall}\s*\(.*?;";
glibc/posix/unistd.h:1121:
ssize_t copy_file_range (int __infd, __off64_t *__pinoff,
			 int __outfd, __off64_t *__poutoff,
			 size_t __length, unsigned int __flags);

......

Testing example:

$ man ./man2/copy_file_range.2 \
  |sed -n '/^EXAMPLES/,/^SEE ALSO/p' \
  |head -n -1 \
  |tail -n +2 \
  >copy_file_range.c
$ gcc -Wall -Wextra -Werror -pedantic
copy_file_range.c -o copy_file_range
$ ./copy_file_range
Usage: ./copy_file_range <source> <destination>
$ tee a >/dev/null
asdf
$ tee b >/dev/null
qwerty
zxcvbn
$ ./copy_file_range a b
$ cat a
asdf
$ cat b
asdf

Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
Alejandro Colomar 2020-12-31 14:24:08 +01:00 committed by Michael Kerrisk
parent 9834f61da2
commit 76c5631fb4
1 changed files with 3 additions and 15 deletions

View File

@ -30,8 +30,8 @@ copy_file_range \- Copy a range of data from one file to another
.B #define _GNU_SOURCE
.B #include <unistd.h>
.PP
.BI "ssize_t copy_file_range(int " fd_in ", loff_t *" off_in ,
.BI " int " fd_out ", loff_t *" off_out ,
.BI "ssize_t copy_file_range(int " fd_in ", off64_t *" off_in ,
.BI " int " fd_out ", off64_t *" off_out ,
.BI " size_t " len ", unsigned int " flags );
.fi
.SH DESCRIPTION
@ -233,26 +233,14 @@ or server-side-copy (in the case of NFS).
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <unistd.h>
/* On versions of glibc before 2.27, we must invoke copy_file_range()
using syscall(2) */
static loff_t
copy_file_range(int fd_in, loff_t *off_in, int fd_out,
loff_t *off_out, size_t len, unsigned int flags)
{
return syscall(__NR_copy_file_range, fd_in, off_in, fd_out,
off_out, len, flags);
}
int
main(int argc, char **argv)
{
int fd_in, fd_out;
struct stat stat;
loff_t len, ret;
off64_t len, ret;
if (argc != 3) {
fprintf(stderr, "Usage: %s <source> <destination>\en", argv[0]);