From 38bfd1ecda2014955c701f7658a4ab55fa5c8b9d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 30 Jun 2023 12:25:53 -0700 Subject: [PATCH] off64_t: prefer off_t for splice, etc. For the few functions that come only in 64-bit off_t flavors, document their APIs as using off_t instead of off64_t, and say also that code should #define _FILE_OFFSET_BITS 64. This documents what user code is (and should be) doing anyway, if it needs to work on legacy 32-bit Linux. --- man2/copy_file_range.2 | 17 ++++++++++++++--- man2/readahead.2 | 8 +++++++- man2/splice.2 | 14 ++++++++++++-- man2/sync_file_range.2 | 9 +++++++-- man3/fopencookie.3 | 14 +++++++++++--- man7/feature_test_macros.7 | 12 ++++++++---- 6 files changed, 59 insertions(+), 15 deletions(-) diff --git a/man2/copy_file_range.2 b/man2/copy_file_range.2 index 6f3aa4971..bb5aa2223 100644 --- a/man2/copy_file_range.2 +++ b/man2/copy_file_range.2 @@ -11,10 +11,11 @@ Standard C library .SH SYNOPSIS .nf .B #define _GNU_SOURCE +.B #define _FILE_OFFSET_BITS 64 .B #include .PP -.BI "ssize_t copy_file_range(int " fd_in ", off64_t *_Nullable " off_in , -.BI " int " fd_out ", off64_t *_Nullable " off_out , +.BI "ssize_t copy_file_range(int " fd_in ", off_t *_Nullable " off_in , +.BI " int " fd_out ", off_t *_Nullable " off_out , .BI " size_t " len ", unsigned int " flags ); .fi .SH DESCRIPTION @@ -224,6 +225,15 @@ gives filesystems an opportunity to implement "copy acceleration" techniques, such as the use of reflinks (i.e., two or more inodes that share pointers to the same copy-on-write disk blocks) or server-side-copy (in the case of NFS). +.PP +.B _FILE_OFFSET_BITS +should be defined to be 64 in code that uses non-null +.I off_in +or +.I off_out +or that takes the address of +.BR copy_file_range , +if the code is intended to be portable to legacy 32-bit platforms. .SH BUGS In Linux 5.3 to Linux 5.18, cross-filesystem copies were implemented by the kernel, @@ -234,6 +244,7 @@ the call failed to copy, while still reporting success. .\" SRC BEGIN (copy_file_range.c) .EX #define _GNU_SOURCE +#define _FILE_OFFSET_BITS 64 #include #include #include @@ -244,7 +255,7 @@ int main(int argc, char *argv[]) { int fd_in, fd_out; - off64_t len, ret; + off_t len, ret; struct stat stat; \& if (argc != 3) { diff --git a/man2/readahead.2 b/man2/readahead.2 index d69795979..62b9e6786 100644 --- a/man2/readahead.2 +++ b/man2/readahead.2 @@ -14,9 +14,10 @@ Standard C library .SH SYNOPSIS .nf .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */" +.B #define _FILE_OFFSET_BITS 64 .B #include .PP -.BI "ssize_t readahead(int " fd ", off64_t " offset ", size_t " count ); +.BI "ssize_t readahead(int " fd ", off_t " offset ", size_t " count ); .fi .SH DESCRIPTION .BR readahead () @@ -73,6 +74,11 @@ Linux. .SH HISTORY Linux 2.4.13, glibc 2.3. +.SH NOTES +.B _FILE_OFFSET_BITS +should be defined to be 64 in code that uses a pointer to +.BR readahead , +if the code is intended to be portable to legacy 32-bit platforms. .SH BUGS .BR readahead () attempts to schedule the reads in the background and return immediately. diff --git a/man2/splice.2 b/man2/splice.2 index dd78e8cd4..829d2e336 100644 --- a/man2/splice.2 +++ b/man2/splice.2 @@ -12,10 +12,11 @@ Standard C library .SH SYNOPSIS .nf .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */" +.B "#define _FILE_OFFSET_BITS 64 .B #include .PP -.BI "ssize_t splice(int " fd_in ", off64_t *_Nullable " off_in , -.BI " int " fd_out ", off64_t *_Nullable " off_out , +.BI "ssize_t splice(int " fd_in ", off_t *_Nullable " off_in , +.BI " int " fd_out ", off_t *_Nullable " off_out , .BI " size_t " len ", unsigned int " flags ); .\" Return type was long before glibc 2.7 .fi @@ -242,6 +243,15 @@ only pointers are copied, not the pages of the buffer. .\" the data and choose to forward it to two or more different .\" users - for things like logging etc.). .\" +.PP +.B _FILE_OFFSET_BITS +should be defined to be 64 in code that uses non-null +.I off_in +or +.I off_out +or that takes the address of +.BR splice , +if the code is intended to be portable to legacy 32-bit platforms. .SH EXAMPLES See .BR tee (2). diff --git a/man2/sync_file_range.2 b/man2/sync_file_range.2 index d633b08ff..0bf17f824 100644 --- a/man2/sync_file_range.2 +++ b/man2/sync_file_range.2 @@ -16,9 +16,10 @@ Standard C library .SH SYNOPSIS .nf .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */" +.B #define _FILE_OFFSET_BITS 64 .B #include .PP -.BI "int sync_file_range(int " fd ", off64_t " offset ", off64_t " nbytes , +.BI "int sync_file_range(int " fd ", off_t " offset ", off_t " nbytes , .BI " unsigned int " flags ); .fi .SH DESCRIPTION @@ -176,7 +177,7 @@ system call that orders the arguments suitably: .in +4n .EX .BI "int sync_file_range2(int " fd ", unsigned int " flags , -.BI " off64_t " offset ", off64_t " nbytes ); +.BI " off_t " offset ", off_t " nbytes ); .EE .in .PP @@ -198,6 +199,10 @@ glibc transparently wraps under the name .BR sync_file_range (). .SH NOTES +.B _FILE_OFFSET_BITS +should be defined to be 64 in code that takes the address of +.BR sync_file_range , +if the code is intended to be portable to legacy 32-bit platforms. .SH SEE ALSO .BR fdatasync (2), .BR fsync (2), diff --git a/man3/fopencookie.3 b/man3/fopencookie.3 index 409a3c81a..08b190394 100644 --- a/man3/fopencookie.3 +++ b/man3/fopencookie.3 @@ -13,6 +13,7 @@ Standard C library .SH SYNOPSIS .nf .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */" +.B #define _FILE_OFFSET_BITS 64 .B #include .PP .BI "FILE *fopencookie(void *restrict " cookie ", const char *restrict " mode , @@ -169,7 +170,7 @@ When called, it receives three arguments: .IP .in +4n .EX -int seek(void *cookie, off64_t *offset, int whence); +int seek(void *cookie, off_t *offset, int whence); .EE .in .IP @@ -351,9 +352,9 @@ memfile_read(void *c, char *buf, size_t size) } \& int -memfile_seek(void *c, off64_t *offset, int whence) +memfile_seek(void *c, off_t *offset, int whence) { - off64_t new_offset; + off_t new_offset; struct memfile_cookie *cookie = c; \& if (whence == SEEK_SET) @@ -451,6 +452,13 @@ main(int argc, char *argv[]) } .EE .\" SRC END +.SH NOTES +.B _FILE_OFFSET_BITS +should be defined to be 64 in code that uses non-null +.I seek +or that takes the address of +.BR fopencookie , +if the code is intended to be portable to legacy 32-bit platforms. .SH SEE ALSO .BR fclose (3), .BR fmemopen (3), diff --git a/man7/feature_test_macros.7 b/man7/feature_test_macros.7 index f1620611c..462fd4abb 100644 --- a/man7/feature_test_macros.7 +++ b/man7/feature_test_macros.7 @@ -113,15 +113,16 @@ feature test macro requirements (this example from .RS +4 .EX .B #define _GNU_SOURCE +.B #define _FILE_OFFSET_BITS 64 .B #include .PP -.BI "ssize_t readahead(int " fd ", off64_t *" offset ", size_t " count ); +.BI "ssize_t readahead(int " fd ", off_t *" offset ", size_t " count ); .EE .RE .PP -This format is employed in cases where only a single -feature test macro can be used to expose the function -declaration, and that macro is not defined by default. +This format is employed in cases where feature macros +expose the function declaration with the correct type, +and these macros are not defined by default. .SS Feature test macros understood by glibc The paragraphs below explain how feature test macros are handled in glibc 2.\fIx\fP, @@ -406,6 +407,9 @@ related to file I/O and filesystem operations into references to their 64-bit counterparts. This is useful for performing I/O on large files (> 2 Gigabytes) on 32-bit systems. +It is also useful when calling functions like +.BR copy_file_range (2) +that were added more recently and that come only in 64-bit flavors. (Defining this macro permits correctly written programs to use large files with only a recompilation being required.) .IP -- 2.41.0