diff -burpN -x CVS -x 'cscope*' -x Makefile.in -x configure -x autom4te.cache -x aclocal.m4 coreutils/ChangeLog coreutils.lcm/ChangeLog --- coreutils/ChangeLog 2005-11-18 16:24:52.000000000 -0600 +++ coreutils.lcm/ChangeLog 2005-11-18 16:24:34.000000000 -0600 @@ -1,3 +1,10 @@ +2005-11-18 Rob Latham + * lib/Makefile.am, lib/buffer-lcm.c, lib/buffer-lcm.h: add code to find + least common multiple of two values, with logic to handle unusual + input (taken from diffutils) + * src/copy.c: use the LCM of the source and dest blocksize when + figuring out the ideal blocksize. + 2005-11-17 Jim Meyering * Version 6.0-cvs. diff -burpN -x CVS -x 'cscope*' -x Makefile.in -x configure -x autom4te.cache -x aclocal.m4 coreutils/lib/buffer-lcm.c coreutils.lcm/lib/buffer-lcm.c --- coreutils/lib/buffer-lcm.c 1969-12-31 18:00:00.000000000 -0600 +++ coreutils.lcm/lib/buffer-lcm.c 2005-11-18 10:04:54.000000000 -0600 @@ -0,0 +1,47 @@ +/* buffer-lcm.c - an lcm routine used for computing optimal buffer size + + Copyright (C) 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + + +/* Least common multiple of two buffer sizes A and B. However, if + either A or B is zero, or if the multiple is greater than LCM_MAX, + return a reasonable buffer size. + + This method was taken from diffutils/lib/cmpbuf.c */ + +#include + +size_t +buffer_lcm (size_t a, size_t b, size_t lcm_max) +{ + size_t lcm, m, n, q, r; + + /* Yield reasonable values if buffer sizes are zero. */ + if (!a) + return b ? b : 8 * 1024; + if (!b) + return a; + + /* n = gcd (a, b) */ + for (m = a, n = b; (r = m % n) != 0; m = n, n = r) + continue; + + /* Yield a if there is an overflow. */ + q = a / n; + lcm = q * b; + return lcm <= lcm_max && lcm / b == q ? lcm : a; +} diff -burpN -x CVS -x 'cscope*' -x Makefile.in -x configure -x autom4te.cache -x aclocal.m4 coreutils/lib/buffer-lcm.h coreutils.lcm/lib/buffer-lcm.h --- coreutils/lib/buffer-lcm.h 1969-12-31 18:00:00.000000000 -0600 +++ coreutils.lcm/lib/buffer-lcm.h 2005-11-18 10:04:54.000000000 -0600 @@ -0,0 +1,23 @@ +/* buffer-lcm.c - an lcm routine used for computing optimal buffer size + + Copyright (C) 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Taken from diffutils/lib/cmpbuf.c */ + +#include + +size_t buffer_lcm(size_t a, size_t b, size_t lcm_max); diff -burpN -x CVS -x 'cscope*' -x Makefile.in -x configure -x autom4te.cache -x aclocal.m4 coreutils/lib/Makefile.am coreutils.lcm/lib/Makefile.am --- coreutils/lib/Makefile.am 2005-10-05 09:54:17.000000000 -0500 +++ coreutils.lcm/lib/Makefile.am 2005-11-18 10:04:54.000000000 -0600 @@ -27,6 +27,7 @@ DEFS += -DLIBDIR=\"$(libdir)\" libcoreutils_a_SOURCES = \ allocsa.c allocsa.h \ + buffer-lcm.c buffer-lcm.h \ euidaccess.h \ exit.h \ fprintftime.c fprintftime.h \ diff -burpN -x CVS -x 'cscope*' -x Makefile.in -x configure -x autom4te.cache -x aclocal.m4 coreutils/src/copy.c coreutils.lcm/src/copy.c --- coreutils/src/copy.c 2005-09-24 22:07:33.000000000 -0500 +++ coreutils.lcm/src/copy.c 2005-11-18 10:04:54.000000000 -0600 @@ -31,6 +31,7 @@ #include "system.h" #include "backupfile.h" +#include "buffer-lcm.h" #include "copy.h" #include "cp-hash.h" #include "dirname.h" @@ -291,7 +292,7 @@ copy_reg (char const *src_name, char con goto close_src_and_dst_desc; } - buf_size = ST_BLKSIZE (sb); + buf_size = buffer_lcm(ST_BLKSIZE (sb), ST_BLKSIZE(src_open_sb), SIZE_MAX); /* Even with --sparse=always, try to create holes only if the destination is a regular file. */