[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: ``install -C'' / unnecessarily updating time stamps
From: |
Paul Eggert |
Subject: |
Re: ``install -C'' / unnecessarily updating time stamps |
Date: |
Mon, 25 Dec 2006 21:23:15 -0800 |
User-agent: |
Gnus/5.1008 (Gnus v5.10.8) Emacs/21.4 (gnu/linux) |
Benoit Sigoure <address@hidden> 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 <address@hidden>
* 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 <address@hidden>
* 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'
- ``install -C'' / unnecessarily updating time stamps, Thomas Schwinge, 2006/12/22
- Re: ``install -C'' / unnecessarily updating time stamps, Paul Eggert, 2006/12/24
- Re: ``install -C'' / unnecessarily updating time stamps, Benoit Sigoure, 2006/12/26
- Re: ``install -C'' / unnecessarily updating time stamps, Benoit Sigoure, 2006/12/26
- Re: ``install -C'' / unnecessarily updating time stamps, Paul Eggert, 2006/12/24
- Re: ``install -C'' / unnecessarily updating time stamps, Thomas Schwinge, 2006/12/25
- Re: ``install -C'' / unnecessarily updating time stamps, Paul Eggert, 2006/12/25
- Re: ``install -C'' / unnecessarily updating time stamps, Akim Demaille, 2006/12/26
- Re: ``install -C'' / unnecessarily updating time stamps, Paul Eggert, 2006/12/25
- Re: ``install -C'' / unnecessarily updating time stamps,
Paul Eggert <=