mirror of
git://git.sv.gnu.org/coreutils.git
synced 2026-02-14 03:12:10 +02:00
cp: port better to old limited hosts
Port better ancient platforms where OFF_T_MAX is only 2**31 - 1, but some devices have more than that many bytes. * src/copy-file-data.c (copy_file_data): Byte count is now count_t, not off_t. All callers changed. Since we need to check for overflow anyway, also check for too-small calls to fadvise.
This commit is contained in:
@@ -493,13 +493,13 @@ infer_scantype (int fd, struct stat const *sb, off_t pos,
|
||||
/* Copy data from input file (descriptor IFD, status IST, initial file
|
||||
offset IPOS, and name INAME) to output file (OFD, OST, OPOS, ONAME).
|
||||
Copy until IBYTES have been copied or until end of file;
|
||||
if IBYTES is OFF_T_MAX that suffices to copy to end of file.
|
||||
if IBYTES is COUNT_MAX that suffices to copy to end of file.
|
||||
Respect copy options X's sparse_mode and reflink_mode settings.
|
||||
Read and update *DEBUG as needed. */
|
||||
bool
|
||||
copy_file_data (int ifd, struct stat const *ist, off_t ipos, char const *iname,
|
||||
int ofd, struct stat const *ost, off_t opos, char const *oname,
|
||||
off_t ibytes, struct cp_options const *x, struct copy_debug *debug)
|
||||
count_t ibytes, struct cp_options const *x, struct copy_debug *debug)
|
||||
{
|
||||
/* Choose a suitable buffer size; it may be adjusted later. */
|
||||
size_t buf_size = io_blksize (ost);
|
||||
@@ -518,7 +518,11 @@ copy_file_data (int ifd, struct stat const *ist, off_t ipos, char const *iname,
|
||||
|| (x->sparse_mode == SPARSE_AUTO
|
||||
&& scantype != PLAIN_SCANTYPE)));
|
||||
|
||||
fdadvise (ifd, ipos, ibytes, FADVISE_SEQUENTIAL);
|
||||
/* Don't bother calling fadvise for small copies, as it is not
|
||||
likely to help performance and might even hurt it. */
|
||||
if (IO_BUFSIZE < ibytes)
|
||||
fdadvise (ifd, ipos, ibytes <= OFF_T_MAX - ipos ? ibytes : 0,
|
||||
FADVISE_SEQUENTIAL);
|
||||
|
||||
/* If not making a sparse file, try to use a more-efficient
|
||||
buffer size. */
|
||||
|
||||
@@ -1048,7 +1048,7 @@ copy_reg (char const *src_name, char const *dst_name,
|
||||
{
|
||||
return_val = copy_file_data (source_desc, &src_open_sb, 0, src_name,
|
||||
dest_desc, &sb, 0, dst_name,
|
||||
OFF_T_MAX, x, ©_debug);
|
||||
COUNT_MAX, x, ©_debug);
|
||||
if (!return_val)
|
||||
goto close_src_and_dst_desc;
|
||||
}
|
||||
|
||||
@@ -321,6 +321,11 @@ struct copy_debug
|
||||
enum copy_debug_val sparse_detection;
|
||||
};
|
||||
|
||||
/* The type of a large counter. Although it is always nonnegative,
|
||||
it is signed to help signed overflow checking catch any bugs. */
|
||||
typedef intmax_t count_t;
|
||||
#define COUNT_MAX INTMAX_MAX
|
||||
|
||||
bool copy (char const *src_name, char const *dst_name,
|
||||
int dst_dirfd, char const *dst_relname,
|
||||
int nonexistent_dst, const struct cp_options *options,
|
||||
@@ -331,7 +336,7 @@ bool copy_file_data (int ifd, struct stat const *ist, off_t ipos,
|
||||
char const *iname,
|
||||
int ofd, struct stat const *ost, off_t opos,
|
||||
char const *oname,
|
||||
off_t ibytes, struct cp_options const *x,
|
||||
count_t ibytes, struct cp_options const *x,
|
||||
struct copy_debug *copy_debug)
|
||||
_GL_ATTRIBUTE_NONNULL ((2, 4, 6, 8, 10, 11));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user