Benoit Sigoure <tsuna@xxxxxxxxxxxxx> writes: > http://lists.gnu.org/archive/html/automake-patches/2006-10/msg00070.html I installed the following to Automake install-sh to implement "install-sh -C", which is the second part of that patch. 2006-12-25 Paul Eggert <eggert@xxxxxxxxxxx> * lib/install-sh (initialize_posix_glob): New var. Use it instead of setting posix_glob inline. (posix_glob): Use '?'/''/: instead of ''/yes/no, for convenience. (cmpprog, CMPPROG): New vars, since we use cmp rather than the diff of Akim's patch. Use LC_ALL before invoking 'ls' when we depend on its output format. Don't use awk; just use the shell's builtin features. Clean up $dsttmp -C detects no installation is needed. * tests/defs.in (is_newest): Renamed from is_younger; the new name is more accurate. All uses changed. (old_timestamp): New var. * tests/instsh2.test: Rewrite to avoid the need for sleeping. 2006-12-25 Akim Demaille <akim@xxxxxxxx> * lib/install-sh: Implement install-sh -C. (This patch is the remaining part of the patch proposed in <http://lists.gnu.org/archive/html/automake-patches/2006-10/msg00077.html>.) (usage): Document it. (copy_on_change): New var. * tests/defs.in (is_younger): New function. * tests/instsh2.test: Check install-sh -C. Index: lib/install-sh =================================================================== RCS file: /cvs/automake/automake/lib/install-sh,v retrieving revision 1.38 diff -u -p -r1.38 install-sh --- lib/install-sh 25 Dec 2006 06:30:28 -0000 1.38 +++ lib/install-sh 26 Dec 2006 05:20:50 -0000 @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2006-12-24.16 +scriptversion=2006-12-25.00 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -61,13 +61,24 @@ fi chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} -posix_glob= +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + posix_mkdir= # Desired mode of installed file. @@ -85,6 +96,7 @@ dst= dir_arg= dst_arg= +copy_on_change=false no_target_directory= usage="\ @@ -102,6 +114,7 @@ Options: --version display version info and exit. -c (ignored) + -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. @@ -111,13 +124,16 @@ Options: -T report an error if DSTFILE is a directory. Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; + -C) copy_on_change=true;; + -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" @@ -373,21 +389,14 @@ do *) prefix='';; esac - case $posix_glob in - '') - if (set -f) 2>/dev/null; then - posix_glob=true - else - posix_glob=false - fi;; - esac + eval "$initialize_posix_glob" oIFS=$IFS IFS=/ - $posix_glob && set -f + $posix_glob set -f set fnord $dstdir shift - $posix_glob && set +f + $posix_glob set +f IFS=$oIFS prefixes= @@ -454,32 +463,49 @@ do { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - # Now rename the file to the real destination. - { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || { - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - } || exit 1 + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 trap '' 0 fi Index: tests/defs.in =================================================================== RCS file: /cvs/automake/automake/tests/defs.in,v retrieving revision 1.40 diff -u -p -r1.40 defs.in --- tests/defs.in 25 Dec 2006 06:30:28 -0000 1.40 +++ tests/defs.in 26 Dec 2006 05:20:50 -0000 @@ -316,6 +316,22 @@ sleep='sleep @MODIFICATION_DELAY@' testsrcdir=$srcdir unset srcdir +# An old timestamp that can be given to a file, in "touch -t" format. +# The time stamp should be portable to all file systems of interest. +# Just for fun, choose the exact time of the announcement of the GNU project +# in UTC; see <http://www.gnu.org/gnu/initial-announcement.html>. +old_timestamp=198309271735.59 + +# is_newest FILE FILES +# -------------------- +# Return false if any file in FILES is newer than FILE. +# Resolve ties in favor of FILE. +is_newest () +{ + test x`find "$@" -newer "$1"` = x +} + + # AUTOMAKE_run status [options...] # -------------------------------- # Run Automake with OPTIONS, and fail if automake Index: tests/instsh2.test =================================================================== RCS file: /cvs/automake/automake/tests/instsh2.test,v retrieving revision 1.7 diff -u -p -r1.7 instsh2.test --- tests/instsh2.test 14 May 2005 20:28:55 -0000 1.7 +++ tests/instsh2.test 26 Dec 2006 05:20:50 -0000 @@ -1,5 +1,5 @@ #! /bin/sh -# Copyright (C) 2002, 2004 Free Software Foundation, Inc. +# Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc. # # This file is part of GNU Automake. # @@ -21,7 +21,6 @@ # Various install-sh checks . ./defs || exit 1 - set -e # Basic errors @@ -82,6 +81,20 @@ test -f d3/y ./install-sh -T x d3 && exit 1 ./install-sh -T x d4// && exit 1 +# Do not change the timestamps when using -C. +echo foo >file +./install-sh -C file d1 +TZ=UTC0 touch -t $old_timestamp d1/file +./install-sh -C file d1 +is_newest file d1/file +echo foo1 >file +./install-sh -C file d1 +diff file d1/file +# Rights must be updated. +./install-sh -C -m 444 file d1 +test -r d1/file +test ! -w d1/file + # Ensure that install-sh works with names that include spaces touch 'a b' mkdir 'x y' _______________________________________________ Autoconf mailing list Autoconf@xxxxxxx http://lists.gnu.org/mailman/listinfo/autoconf