Skip to contentSkip to conversation

copy_file_range.2: SYNOPSIS: Fix prototype parameter types

PATCH In review Alejandro Colomar 2 participants 10 messages Dec 30, 2020 – Jan 2, 2021 Man-pages: manual pages for Linux -- Sections 2, 3, 4, 5, and 7

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 copy_file_range.2: SYNOPSIS: Fix prototype parameter types

Glibc uses 'off64_t' instead of 'loff_t'.

This patch doesn't change the types in the code example, because it uses the Linux syscall, and not the glibc wrapper.

......

$ 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);
---
 man2/copy_file_range.2 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
man2/copy_file_range.2 +2 -2
index 1692aa44a..6f4708c4b 100644
@@ -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
Signature · 1 line
2.29.2
#1 lore raw

Hi Alex,

Quoted 1 line · Alejandro Colomar

Glibc uses 'off64_t' instead of 'loff_t'.

Okay.

Quoted 2 lines

This patch doesn't change the types in the code example, because it uses the Linux syscall, and not the glibc wrapper.

I think the example probably also needs fixing then. There's no longer a need for syscall(2) in this example, I think.

Thanks,

Michael

Quoted 32 lines

......

$ 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);
---
 man2/copy_file_range.2 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
man2/copy_file_range.2 +2 -2
index 1692aa44a..6f4708c4b 100644
@@ -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
Signature · 3 lines
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
#2 lore raw
Quoted 5 lines · Michael Kerrisk (man-pages)

Hi Alex,

Quoted 1 line · Alejandro Colomar

Glibc uses 'off64_t' instead of 'loff_t'.

Quoted 7 lines

Okay.

Quoted 2 lines

This patch doesn't change the types in the code example, because it uses the Linux syscall, and not the glibc wrapper.

I think the example probably also needs fixing then. There's no longer a need for syscall(2) in this example, I think.

Hi Michael,

I thought the same, but glibc 2.26 is still supported, and lacks the wrapper.
Would you change it already?

Thanks,

Alex

Quoted 39 lines

Thanks,

Michael

Quoted 32 lines

......

$ 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);
---
 man2/copy_file_range.2 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
man2/copy_file_range.2 +2 -2
index 1692aa44a..6f4708c4b 100644
@@ -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
#3 lore raw

Hi Alex,

Quoted 13 lines · Alejandro Colomar (man-pages)
Quoted 10 lines · Michael Kerrisk (man-pages)

Hi Alex,

Quoted 1 line · Alejandro Colomar

Glibc uses 'off64_t' instead of 'loff_t'.

Okay.

Quoted 2 lines

This patch doesn't change the types in the code example, because it uses the Linux syscall, and not the glibc wrapper.

Quoted 8 lines
Quoted 2 lines

I think the example probably also needs fixing then. There's no longer a need for syscall(2) in this example, I think.

Hi Michael,

I thought the same, but glibc 2.26 is still supported, and lacks the wrapper.
Would you change it already?

Yes.

Thanks,

Michael

Signature · 3 lines
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
#4 lore raw

Hi Michael,

I'm fixing the example, and I trying to see if I can remove some of the headers with the change. However, it's difficult to find that for sure, at least from the manual pages alone. I think that's one of the biggest inconsistencies in the pages and I'd like to fix that some day.

Also, I'll resend the old patch documenting off64_t in system_data_types(7), given that this interface uses it.

For the SYNOPSIS sections of man2 and man3,
I'll try to have a single header,
and if there are some other headers needed (for type definitions, or other), I'll add a comment to all of them, so that it's clear why each header is needed.

See stat(2) as an example of what I don't like:

[[
SYNOPSIS

       #include <sys/types.h>
       #include <sys/stat.h>
       #include <unistd.h>

       int stat(const char *pathname, struct stat *statbuf);
       int fstat(int fd, struct stat *statbuf);
       int lstat(const char *pathname, struct stat *statbuf);

       #include <fcntl.h>           /* Definition of AT_* constants */
       #include <sys/stat.h>

       int fstatat(int dirfd, const char *pathname, struct stat *statbuf,
                   int flags);

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       lstat():
           /* glibc 2.19 and earlier */ _BSD_SOURCE
               || /* Since glibc 2.20 */ _DEFAULT_SOURCE
               || _XOPEN_SOURCE >= 500
               || /* Since glibc 2.10: */ _POSIX_C_SOURCE >= 200112L

       fstatat():
           Since glibc 2.10:
               _POSIX_C_SOURCE >= 200809L
           Before glibc 2.10:
               _ATFILE_SOURCE

]]

Why should one include all of those headers?
Which has the function definition?
And what do the others provide?

Cheers,

Alex

Quoted 32 lines · Michael Kerrisk (man-pages)

Hi Alex,

Quoted 13 lines · Alejandro Colomar (man-pages)
Quoted 10 lines · Michael Kerrisk (man-pages)

Hi Alex,

Quoted 1 line · Alejandro Colomar

Glibc uses 'off64_t' instead of 'loff_t'.

Okay.

Quoted 2 lines

This patch doesn't change the types in the code example, because it uses the Linux syscall, and not the glibc wrapper.

Quoted 8 lines
Quoted 2 lines

I think the example probably also needs fixing then. There's no longer a need for syscall(2) in this example, I think.

Hi Michael,

I thought the same, but glibc 2.26 is still supported, and lacks the wrapper.
Would you change it already?

Yes.

Thanks,

Michael

#5 lore raw

Hi Alex,

Quoted 48 lines · Alejandro Colomar (man-pages)

Hi Michael,

I'm fixing the example, and I trying to see if I can remove some of the headers with the change. However, it's difficult to find that for sure, at least from the manual pages alone. I think that's one of the biggest inconsistencies in the pages and I'd like to fix that some day.

Also, I'll resend the old patch documenting off64_t in system_data_types(7), given that this interface uses it.

For the SYNOPSIS sections of man2 and man3,
I'll try to have a single header,
and if there are some other headers needed (for type definitions, or other), I'll add a comment to all of them, so that it's clear why each header is needed.

See stat(2) as an example of what I don't like:

[[
SYNOPSIS

       #include <sys/types.h>
       #include <sys/stat.h>
       #include <unistd.h>

       int stat(const char *pathname, struct stat *statbuf);
       int fstat(int fd, struct stat *statbuf);
       int lstat(const char *pathname, struct stat *statbuf);

       #include <fcntl.h>           /* Definition of AT_* constants */
       #include <sys/stat.h>

       int fstatat(int dirfd, const char *pathname, struct stat *statbuf,
                   int flags);
   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       lstat():
           /* glibc 2.19 and earlier */ _BSD_SOURCE
               || /* Since glibc 2.20 */ _DEFAULT_SOURCE
               || _XOPEN_SOURCE >= 500
               || /* Since glibc 2.10: */ _POSIX_C_SOURCE >= 200112L

       fstatat():
           Since glibc 2.10:
               _POSIX_C_SOURCE >= 200809L
           Before glibc 2.10:
               _ATFILE_SOURCE
Quoted 5 lines

]]

Why should one include all of those headers?
Which has the function definition?
And what do the others provide?

There's a lot of history here, and I do not know all of it.

In old standards, <sys/types.h> was often required for various APIs. Eg.e., in XPGv4.2 (1994), there is the following spec:

OH #include <sys/types.h>

    #include <sys/stat.h>
    int stat(const char *path, struct stat *buf);

And the standard says that "OH" means
"This indicates that the marked header is not required on
XSI-conformant systems. This is an extension to certain formal standards where the full synopsis is required."

So, it seems that some ancient systems may have requried this header (<sys/types.h>) for portability, presumably because <sys/stat.h> did not itself define various types used in the 'stat' structure (at least on some systems. So, for portability reasons, the Linux manual page mentions this header file.

I have no explanation of <unistd.h>. That was there when I inherited the project (and back then there was no version control). But it was there back in 1995. Perhaps there's a historical reason. Perhaps there was a mistake. (No version control, no mailing list, so who knows.)

I'm not averse to seeing some of this cleaned up. It's not fun work, of course! Maybe POSIX.1-2001 (as well as 2008) might need to be checked, since info in that standard is a snapshot of history that could conceivably still be relevant now (in terms of portability to implementations that are older but possibly still relevant).

Cheers,

Michael

Signature · 3 lines
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
#6 lore raw

PATCH 1/1 Various pages: Consistently use 'unsigned int'

In reply to Michael Kerrisk (man-pages)

Most pages use 'unsigned int' (and the kernel too). Make them all do so.

$ find man? -type f \
  |xargs sed -i \
	-e 's/unsigned \*/unsigned int */g'
	-e 's/unsigned "/unsigned int "/g';
---
 man2/getcpu.2     | 4 ++--
 man2/io_setup.2   | 2 +-
 man2/mbind.2      | 2 +-
 man3/cfree.3      | 2 +-
 man3/des_crypt.3  | 8 ++++----
 man3/getrpcport.3 | 2 +-
 man3/random.3     | 4 ++--
 man3/xdr.3        | 2 +-
 8 files changed, 13 insertions(+), 13 deletions(-)
man2/getcpu.2 +2 -2
index fc36b43b5..46e4d53ff 100644
@@ -16,8 +16,8 @@ getcpu \- determine CPU and NUMA node on which the calling thread is running
 .nf
 .B #include <linux/getcpu.h>
 .PP
-.BI "int getcpu(unsigned *" cpu ", unsigned *" node \
-", struct getcpu_cache *" tcache );
+.BI "int getcpu(unsigned int *" cpu ", unsigned int *" node ,
+.BI "           struct getcpu_cache *" tcache );
 .fi
 .SH DESCRIPTION
 The
man2/io_setup.2 +1 -1
index e08d19bb8..bd52a5311 100644
@@ -11,7 +11,7 @@ io_setup \- create an asynchronous I/O context
 .nf
 .BR "#include <linux/aio_abi.h>" "          /* Defines needed types */"
 .PP
-.BI "long io_setup(unsigned " nr_events ", aio_context_t *" ctx_idp );
+.BI "long io_setup(unsigned int " nr_events ", aio_context_t *" ctx_idp );
 .fi
 .PP
 .IR Note :
man2/mbind.2 +1 -1
index bf66dfc6c..d98969e7f 100644
@@ -41,7 +41,7 @@ mbind \- set memory policy for a memory range
 .PP
 .BI "long mbind(void *" addr ", unsigned long " len  ", int " mode ,
 .BI "           const unsigned long *" nodemask  ", unsigned long " maxnode ,
-.BI "           unsigned " flags );
+.BI "           unsigned int " flags );
 .PP
 Link with \fI\-lnuma\fP.
 .fi
man3/cfree.3 +1 -1
index 2a09527a7..74223db71 100644
@@ -36,7 +36,7 @@ cfree \- free allocated memory
 .BI "void cfree(void *" ptr );
 .PP
 /* In SCO OpenServer */
-.BI "void cfree(char *" ptr ", unsigned " num ", unsigned " size );
+.BI "void cfree(char *" ptr ", unsigned int " num ", unsigned int " size );
 .PP
 /* In Solaris watchmalloc.so.1 */
 .BI "void cfree(void *" ptr ", size_t " nelem ", size_t " elsize );
man3/des_crypt.3 +4 -4
index 7f34c1585..66fe78337 100644
@@ -21,11 +21,11 @@ DES encryption
 .\" .B #include <des_crypt.h>
 .B #include <rpc/des_crypt.h>
 .PP
-.BI "int ecb_crypt(char *" key ", char *" data ", unsigned " datalen ,
-.BI "              unsigned " mode );
+.BI "int ecb_crypt(char *" key ", char *" data ", unsigned int " datalen ,
+.BI "              unsigned int " mode );
 .PP
-.BI "int cbc_crypt(char *" key ", char *" data ", unsigned " datalen ,
-.BI "              unsigned " mode ", char *" ivec );
+.BI "int cbc_crypt(char *" key ", char *" data ", unsigned int " datalen ,
+.BI "              unsigned int " mode ", char *" ivec );
 .PP
 .BI "void des_setparity(char *" key );
 .PP
man3/getrpcport.3 +1 -1
index 2eba5d30a..d5753d39b 100644
@@ -13,7 +13,7 @@ getrpcport \- get RPC port number
 .B "#include <rpc/rpc.h>"
 .PP
 .BI "int getrpcport(const char *" host ", unsigned long " prognum ,
-.BI "               unsigned long " versnum ", unsigned " proto );
+.BI "               unsigned long " versnum ", unsigned int " proto );
 .fi
 .SH DESCRIPTION
 .BR getrpcport ()
man3/random.3 +2 -2
index d1b8e1981..c9066e446 100644
@@ -39,9 +39,9 @@ random, srandom, initstate, setstate \- random number generator
 .PP
 .B long random(void);
 .PP
-.BI "void srandom(unsigned " seed );
+.BI "void srandom(unsigned int " seed );
 .PP
-.BI "char *initstate(unsigned " seed ", char *" state ", size_t " n );
+.BI "char *initstate(unsigned int " seed ", char *" state ", size_t " n );
 .PP
 .BI "char *setstate(char *" state );
 .fi
man3/xdr.3 +1 -1
index 713827567..978a50660 100644
@@ -433,7 +433,7 @@ C characters and their external representations.
 This routine returns one if it succeeds, zero otherwise.
 .PP
 .nf
-.BI "bool_t xdr_u_int(XDR *" xdrs ", unsigned *" up );
+.BI "bool_t xdr_u_int(XDR *" xdrs ", unsigned int *" up );
 .fi
 .IP
 A filter primitive that translates between C
Signature · 1 line
2.29.2
#7 lore raw

Re: [PATCH] Various pages: Consistently use 'unsigned int'

Hi Alex,

Quoted 9 lines · Alejandro Colomar

Most pages use 'unsigned int' (and the kernel too). Make them all do so.

$ find man? -type f \
  |xargs sed -i \
	-e 's/unsigned \*/unsigned int */g'
	-e 's/unsigned "/unsigned int "/g';

Good work. Patch applied (manually, because I shot myself in the foot with the other recent work in SYNOPSIS).

Cheers,

Michael

Quoted 128 lines
---
 man2/getcpu.2     | 4 ++--
 man2/io_setup.2   | 2 +-
 man2/mbind.2      | 2 +-
 man3/cfree.3      | 2 +-
 man3/des_crypt.3  | 8 ++++----
 man3/getrpcport.3 | 2 +-
 man3/random.3     | 4 ++--
 man3/xdr.3        | 2 +-
 8 files changed, 13 insertions(+), 13 deletions(-)
man2/getcpu.2 +2 -2
index fc36b43b5..46e4d53ff 100644
@@ -16,8 +16,8 @@ getcpu \- determine CPU and NUMA node on which the calling thread is running
 .nf
 .B #include <linux/getcpu.h>
 .PP
-.BI "int getcpu(unsigned *" cpu ", unsigned *" node \
-", struct getcpu_cache *" tcache );
+.BI "int getcpu(unsigned int *" cpu ", unsigned int *" node ,
+.BI "           struct getcpu_cache *" tcache );
 .fi
 .SH DESCRIPTION
 The
man2/io_setup.2 +1 -1
index e08d19bb8..bd52a5311 100644
@@ -11,7 +11,7 @@ io_setup \- create an asynchronous I/O context
 .nf
 .BR "#include <linux/aio_abi.h>" "          /* Defines needed types */"
 .PP
-.BI "long io_setup(unsigned " nr_events ", aio_context_t *" ctx_idp );
+.BI "long io_setup(unsigned int " nr_events ", aio_context_t *" ctx_idp );
 .fi
 .PP
 .IR Note :
man2/mbind.2 +1 -1
index bf66dfc6c..d98969e7f 100644
@@ -41,7 +41,7 @@ mbind \- set memory policy for a memory range
 .PP
 .BI "long mbind(void *" addr ", unsigned long " len  ", int " mode ,
 .BI "           const unsigned long *" nodemask  ", unsigned long " maxnode ,
-.BI "           unsigned " flags );
+.BI "           unsigned int " flags );
 .PP
 Link with \fI\-lnuma\fP.
 .fi
man3/cfree.3 +1 -1
index 2a09527a7..74223db71 100644
@@ -36,7 +36,7 @@ cfree \- free allocated memory
 .BI "void cfree(void *" ptr );
 .PP
 /* In SCO OpenServer */
-.BI "void cfree(char *" ptr ", unsigned " num ", unsigned " size );
+.BI "void cfree(char *" ptr ", unsigned int " num ", unsigned int " size );
 .PP
 /* In Solaris watchmalloc.so.1 */
 .BI "void cfree(void *" ptr ", size_t " nelem ", size_t " elsize );
man3/des_crypt.3 +4 -4
index 7f34c1585..66fe78337 100644
@@ -21,11 +21,11 @@ DES encryption
 .\" .B #include <des_crypt.h>
 .B #include <rpc/des_crypt.h>
 .PP
-.BI "int ecb_crypt(char *" key ", char *" data ", unsigned " datalen ,
-.BI "              unsigned " mode );
+.BI "int ecb_crypt(char *" key ", char *" data ", unsigned int " datalen ,
+.BI "              unsigned int " mode );
 .PP
-.BI "int cbc_crypt(char *" key ", char *" data ", unsigned " datalen ,
-.BI "              unsigned " mode ", char *" ivec );
+.BI "int cbc_crypt(char *" key ", char *" data ", unsigned int " datalen ,
+.BI "              unsigned int " mode ", char *" ivec );
 .PP
 .BI "void des_setparity(char *" key );
 .PP
man3/getrpcport.3 +1 -1
index 2eba5d30a..d5753d39b 100644
@@ -13,7 +13,7 @@ getrpcport \- get RPC port number
 .B "#include <rpc/rpc.h>"
 .PP
 .BI "int getrpcport(const char *" host ", unsigned long " prognum ,
-.BI "               unsigned long " versnum ", unsigned " proto );
+.BI "               unsigned long " versnum ", unsigned int " proto );
 .fi
 .SH DESCRIPTION
 .BR getrpcport ()
man3/random.3 +2 -2
index d1b8e1981..c9066e446 100644
@@ -39,9 +39,9 @@ random, srandom, initstate, setstate \- random number generator
 .PP
 .B long random(void);
 .PP
-.BI "void srandom(unsigned " seed );
+.BI "void srandom(unsigned int " seed );
 .PP
-.BI "char *initstate(unsigned " seed ", char *" state ", size_t " n );
+.BI "char *initstate(unsigned int " seed ", char *" state ", size_t " n );
 .PP
 .BI "char *setstate(char *" state );
 .fi
man3/xdr.3 +1 -1
index 713827567..978a50660 100644
@@ -433,7 +433,7 @@ C characters and their external representations.
 This routine returns one if it succeeds, zero otherwise.
 .PP
 .nf
-.BI "bool_t xdr_u_int(XDR *" xdrs ", unsigned *" up );
+.BI "bool_t xdr_u_int(XDR *" xdrs ", unsigned int *" up );
 .fi
 .IP
 A filter primitive that translates between C
Signature · 3 lines
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
#8 lore raw

PATCH v2 1/1 copy_file_range.2: Document glibc wrapper instead of kernel syscall

In reply to Michael Kerrisk (man-pages)

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 \
Quoted 1 line

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
---
 man2/copy_file_range.2 | 18 +++---------------
 1 file changed, 3 insertions(+), 15 deletions(-)
man2/copy_file_range.2 +3 -15
index 1692aa44a..611a39b80 100644
@@ -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]);
Signature · 1 line
2.29.2
#9 lore raw

Re: [PATCH v2] copy_file_range.2: Document glibc wrapper instead of kernel syscall

Hello Alex,

Quoted 40 lines · Alejandro Colomar

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 \
Quoted 1 line

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
Quoted 1 line

Thanks! Patch applied.

Cheers,

Michael

Quoted 48 lines
---
 man2/copy_file_range.2 | 18 +++---------------
 1 file changed, 3 insertions(+), 15 deletions(-)
man2/copy_file_range.2 +3 -15
index 1692aa44a..611a39b80 100644
@@ -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]);
Signature · 3 lines
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/