This patch fixes DATA, HEADERS, PYTHON, SCRIPTS, and TEXINFOS installation to fail if any of the install commands failed. The new tests exercise this failure by trying to install some unreadable files. They also use many files (81 per variable) to exercise the splitting code. Never mind the fact that SCRIPTS aren't installed efficiently yet, it merely slow down the test execution.
Cheers, Ralf 2008-09-07 Ralf Wildenhues <[EMAIL PROTECTED]> Exit upon `install' failure, part one. * lib/am/data.am (install-%DIR%%PRIMARY%): Exit if any install command fails. * lib/am/python.am (install-%DIR%PYTHON): Likewise. * lib/am/scripts.am (install-%DIR%SCRIPTS): Likewise. * lib/am/texinfos.am (install-dvi-am, install-html-am) (install-info-am:, install-pdf-am): Likewise. * tests/instmany.test: New test, for SCRIPTS, DATA, and HEADERS. * tests/instmany-python.test: New test, for PYTHON. * tests/Makefile.am: Adjust. diff --git a/lib/am/data.am b/lib/am/data.am index 3536f94..a7039c0 100644 --- a/lib/am/data.am +++ b/lib/am/data.am @@ -43,7 +43,8 @@ if %?BASE% done | $(am__base_list) | \ while read files; do \ echo " $(%DIR%%PRIMARY%_INSTALL) $$files '$(DESTDIR)$(%NDIR%dir)'"; \ - $(%DIR%%PRIMARY%_INSTALL) $$files "$(DESTDIR)$(%NDIR%dir)"; done + $(%DIR%%PRIMARY%_INSTALL) $$files "$(DESTDIR)$(%NDIR%dir)" || exit $$?; \ + done else !%?BASE% @list='$(%DIR%_%PRIMARY%)'; $(am__nobase_list) | \ while read dir files; do \ @@ -55,7 +56,7 @@ else !%?BASE% echo "$(MKDIR_P) '$(DESTDIR)$(%NDIR%dir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(%NDIR%dir)/$$dir"; }; \ echo " $(%DIR%%PRIMARY%_INSTALL) $$xfiles '$(DESTDIR)$(%NDIR%dir)/$$dir'"; \ - $(%DIR%%PRIMARY%_INSTALL) $$xfiles "$(DESTDIR)$(%NDIR%dir)/$$dir"; }; \ + $(%DIR%%PRIMARY%_INSTALL) $$xfiles "$(DESTDIR)$(%NDIR%dir)/$$dir" || exit $$?; }; \ done endif !%?BASE% endif %?INSTALL% diff --git a/lib/am/python.am b/lib/am/python.am index 2c02275..7a1cdb2 100644 --- a/lib/am/python.am +++ b/lib/am/python.am @@ -43,10 +43,12 @@ if %?BASE% list2="$$list2 $$b$$p"; \ else :; fi; \ done; \ - test -z "$$list2" || { \ + for file in $$list2; do echo $$file; done | $(am__base_list) | \ + while read files; do \ ## Don't perform translation, since script name is important. - echo " $(%DIR%PYTHON_INSTALL) $$list2 '$(DESTDIR)$(%NDIR%dir)'"; \ - $(%DIR%PYTHON_INSTALL) $$list2 "$(DESTDIR)$(%NDIR%dir)"; }; \ + echo " $(%DIR%PYTHON_INSTALL) $$files '$(DESTDIR)$(%NDIR%dir)'"; \ + $(%DIR%PYTHON_INSTALL) $$files "$(DESTDIR)$(%NDIR%dir)" || exit $$?; \ + done || exit $$?; \ ## Byte-compile must be done at install time, since file times are ## encoded in the actual files. if test -n "$$dlist"; then \ @@ -70,7 +72,7 @@ else !%?BASE% $(MKDIR_P) "$(DESTDIR)$(%NDIR%dir)/$$dir"; }; \ ## Don't perform translation, since script name is important. echo " $(%DIR%PYTHON_INSTALL) $$xfiles '$(DESTDIR)$(%NDIR%dir)/$$dir'"; \ - $(%DIR%PYTHON_INSTALL) $$xfiles "$(DESTDIR)$(%NDIR%dir)/$$dir"; }; \ + $(%DIR%PYTHON_INSTALL) $$xfiles "$(DESTDIR)$(%NDIR%dir)/$$dir" || exit $$?; }; \ ## Byte-compile must be done at install time, since file times are ## encoded in the actual files. if test -n "$$dlist"; then \ diff --git a/lib/am/scripts.am b/lib/am/scripts.am index 64b194b..56f491a 100644 --- a/lib/am/scripts.am +++ b/lib/am/scripts.am @@ -1,6 +1,6 @@ ## automake - create Makefile.in from Makefile.am -## Copyright (C) 1994, 1995, 1996, 1998, 1999, 2001, 2003, 2004, 2006, 2007 -## Free Software Foundation, Inc. +## Copyright (C) 1994, 1995, 1996, 1998, 1999, 2001, 2003, 2004, 2006, 2007, +## 2008 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 @@ -50,7 +50,7 @@ install-%DIR%SCRIPTS: $(%DIR%_SCRIPTS) ## Prepend the directory part if nobase_ is used. ?!BASE? f=`echo "$$p" | sed 's|[^/]*$$||'`"$$f"; \ echo " $(%DIR%SCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(%NDIR%dir)/$$f'"; \ - $(%DIR%SCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(%NDIR%dir)/$$f"; \ + $(%DIR%SCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(%NDIR%dir)/$$f" || exit $$?; \ else :; fi; \ done endif %?INSTALL% diff --git a/lib/am/texinfos.am b/lib/am/texinfos.am index 0f482a8..9cfc645 100644 --- a/lib/am/texinfos.am +++ b/lib/am/texinfos.am @@ -150,7 +150,8 @@ install-dvi-am: $(DVIS) done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)"; done + $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \ + done install-html-am: $(HTMLS) @$(NORMAL_INSTALL) @@ -162,7 +163,7 @@ install-html-am: $(HTMLS) echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \ $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \ - $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f"; \ + $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \ else \ list2="$$list2 $$d$$p"; \ fi; \ @@ -170,7 +171,8 @@ install-html-am: $(HTMLS) test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)"; done; } + $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ + done; } install-info-am: $(INFO_DEPS) @$(NORMAL_INSTALL) @@ -202,7 +204,7 @@ install-info-am: $(INFO_DEPS) done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)"; done + $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done @$(POST_INSTALL) ## Only run this code if install-info actually exists, and it is not ## the Debian install-info. FIXME: once Debian install-info goes @@ -241,7 +243,7 @@ install-pdf-am: $(PDFS) done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)"; done + $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done install-ps-am: $(PSS) @$(NORMAL_INSTALL) @@ -252,7 +254,7 @@ install-ps-am: $(PSS) done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)"; done + $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done else ! %?LOCAL-TEXIS% install-dvi-am: diff --git a/tests/Makefile.am b/tests/Makefile.am index 6aa5d5c..54ac671 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -306,6 +306,8 @@ instexec.test \ insthook.test \ instman.test \ instman2.test \ +instmany.test \ +instmany-python.test \ instspc.test \ interp.test \ interp2.test \ diff --git a/tests/instmany-python.test b/tests/instmany-python.test new file mode 100755 index 0000000..beace0c --- /dev/null +++ b/tests/instmany-python.test @@ -0,0 +1,135 @@ +#! /bin/sh +# Copyright (C) 2008 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 3, 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, see <http://www.gnu.org/licenses/>. + +# Installing many files should not exceed the command line length limit. + +# This is the python sister test of instmany.test, see there for details. + +required='non-root python' +. ./defs || Exit 1 + +set -e + +limit=2500 +subdir=long_subdir_name_with_many_characters +nfiles=81 + +list=`(seq 1 $nfiles) 2>/dev/null || { + i=1 + while test $i -le $nfiles; do + echo $i + i=\`expr $i + 1\` + done; }` + +sed "s|@limit@|$limit|g" >myinstall.in <<'END' +#! /bin/sh +# Fake install script. This doesn't really install +# (the INSTALL path below would be wrong outside this directory). [EMAIL PROTECTED]@ +INSTALL='@INSTALL@' +len=`expr "$INSTALL $*" : ".*" 2>/dev/null || echo $limit` +if test $len -ge $limit; then + echo "$0: safe command line limit of $limit characters exceeded" >&2 + exit 1 +fi +exit 0 +END + +# Creative quoting in the next line to please maintainer-check. +sed "s|@limit@|$limit|g" >'rm' <<'END' +#! /bin/sh [EMAIL PROTECTED]@ +PATH=$save_PATH +export PATH +RM='rm -f' +len=`expr "$RM $*" : ".*" 2>/dev/null || echo $limit` +if test $len -ge $limit; then + echo "$0: safe command line limit of $limit characters exceeded" >&2 + exit 1 +fi +exec $RM "$@" +exit 1 +END + +chmod +x rm + +cat >>configure.in <<END +AM_PATH_PYTHON +AC_CONFIG_FILES([myinstall], [chmod +x ./myinstall]) +AC_CONFIG_FILES([$subdir/Makefile]) +AC_OUTPUT +END + +cat >Makefile.am <<END +SUBDIRS = $subdir +END + +mkdir $subdir +cd $subdir + +cat >Makefile.am <<'END' +python_PYTHON = +nobase_python_PYTHON = +END + +for n in $list; do + cat >>Makefile.am <<END +python_PYTHON += python$n.py +nobase_python_PYTHON += npython$n.py +END + echo >python$n.py + echo >npython$n.py +done + +cd .. +$ACLOCAL +$AUTOCONF +$AUTOMAKE --add-missing + +instdir=`pwd`/inst +mkdir build +cd build +../configure --prefix="$instdir" +$MAKE +# Try whether native install (or install-sh) works. +$MAKE install +$MAKE uninstall +test `find "$instdir" -type f -print | wc -l` = 0 + +# Try whether we don't exceed the low limit. +INSTALL='$(SHELL) $(top_builddir)/myinstall' $MAKE -e install +env save_PATH="$PATH" PATH="`pwd`/..:$PATH" $MAKE uninstall + +cd $subdir +srcdir=../../$subdir + +# Ensure 'make install' fails when 'install' fails. + +for file in python3.py python$nfiles.py +do + chmod a-r $srcdir/$file + $MAKE install && Exit 1 + chmod u+r $srcdir/$file +done + +for file in npython3.py npython$nfiles.py +do + chmod a-r $srcdir/$file + $MAKE install && Exit 1 + chmod u+r $srcdir/$file +done + +: diff --git a/tests/instmany.test b/tests/instmany.test new file mode 100755 index 0000000..f67e6fa --- /dev/null +++ b/tests/instmany.test @@ -0,0 +1,193 @@ +#! /bin/sh +# Copyright (C) 2008 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 3, 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, see <http://www.gnu.org/licenses/>. + +# Installing many files should not exceed the command line length limit. +# Here, the main issue is that we may prepend `$(srcdir)/' to each file, +# which may cause much longer command lines. The list of files must +# anyway remain below the limit, otherwise `make' won't be able to even +# fork the command. +# +# Further, the install rule should honor failures of the install program. + +# Python is done in the sister test. +# For texinfos, we expand names using $(srcdir) in the first place. +# Let's hope nobody uses many texinfos. + + +required=non-root # hope to catch 'chmod a-r'-challenged file systems. +. ./defs || Exit 1 + +set -e + +# In order to have a useful test on modern systems (which have a high +# limit, if any), use a fake install program that errors out for more +# than 2K characters in a command line. The POSIX limit is 4096, but +# that may include space taken up by the environment. + +limit=2500 +subdir=long_subdir_name_with_many_characters +nfiles=81 + +# Let's use `seq' if available, it's faster than the loop. +list=`(seq 1 $nfiles) 2>/dev/null || { + i=1 + while test $i -le $nfiles; do + echo $i + i=\`expr $i + 1\` + done; }` + +sed "s|@limit@|$limit|g" >myinstall.in <<'END' +#! /bin/sh +# Fake install script. This doesn't really install +# (the INSTALL path below would be wrong outside this directory). [EMAIL PROTECTED]@ +INSTALL='@INSTALL@' +len=`expr "$INSTALL $*" : ".*" 2>/dev/null || echo $limit` +if test $len -ge $limit; then + echo "$0: safe command line limit of $limit characters exceeded" >&2 + exit 1 +fi +exit 0 +END + +# Creative quoting in the next line to please maintainer-check. +sed "s|@limit@|$limit|g" >'rm' <<'END' +#! /bin/sh [EMAIL PROTECTED]@ +PATH=$save_PATH +export PATH +RM='rm -f' +len=`expr "$RM $*" : ".*" 2>/dev/null || echo $limit` +if test $len -ge $limit; then + echo "$0: safe command line limit of $limit characters exceeded" >&2 + exit 1 +fi +exec $RM "$@" +exit 1 +END + +chmod +x rm + +cat >>configure.in <<END +AC_CONFIG_FILES([myinstall], [chmod +x ./myinstall]) +AC_CONFIG_FILES([$subdir/Makefile]) +AC_OUTPUT +END + +cat >Makefile.am <<END +SUBDIRS = $subdir +END + +mkdir $subdir +cd $subdir + +cat >Makefile.am <<'END' +bin_SCRIPTS = +nobase_bin_SCRIPTS = +data_DATA = +nobase_data_DATA = +include_HEADERS = +nobase_include_HEADERS = +END + +for n in $list; do + cat >>Makefile.am <<END +bin_SCRIPTS += script$n +nobase_bin_SCRIPTS += nscript$n +data_DATA += data$n +nobase_data_DATA += ndata$n +include_HEADERS += header$n.h +nobase_include_HEADERS += nheader$n.h +END + echo >script$n + echo >nscript$n + echo >data$n + echo >ndata$n + echo >header$n.h + echo >nheader$n.h +done + +cd .. +$ACLOCAL +$AUTOCONF +$AUTOMAKE --add-missing + +instdir=`pwd`/inst +mkdir build +cd build +../configure --prefix="$instdir" +$MAKE +# Try whether native install (or install-sh) works. +$MAKE install +$MAKE uninstall +test `find "$instdir" -type f -print | wc -l` = 0 + +# Try whether we don't exceed the low limit. +INSTALL='$(SHELL) $(top_builddir)/myinstall' $MAKE -e install +env save_PATH="$PATH" PATH="`pwd`/..:$PATH" $MAKE uninstall + +cd $subdir +srcdir=../../$subdir + +# Ensure 'make install' fails when 'install' fails. + +# We cheat here, for efficiency, knowing the internal rule names. +# For correctness, one should `$MAKE install' here always, or at +# least use install-exec or install-data. + +for file in script3 script$nfiles +do + chmod a-r $srcdir/$file + $MAKE install-binSCRIPTS && Exit 1 + chmod u+r $srcdir/$file +done + +for file in nscript3 nscript$nfiles +do + chmod a-r $srcdir/$file + $MAKE install-nobase_binSCRIPTS && Exit 1 + chmod u+r $srcdir/$file +done + +for file in data3 data$nfiles +do + chmod a-r $srcdir/$file + $MAKE install-dataDATA && Exit 1 + chmod u+r $srcdir/$file +done + +for file in ndata3 ndata$nfiles +do + chmod a-r $srcdir/$file + $MAKE install-nobase_dataDATA && Exit 1 + chmod u+r $srcdir/$file +done + +for file in header3.h header$nfiles.h +do + chmod a-r $srcdir/$file + $MAKE install-includeHEADERS && Exit 1 + chmod u+r $srcdir/$file +done + +for file in nheader3.h nheader$nfiles.h +do + chmod a-r $srcdir/$file + $MAKE install-nobase_includeHEADERS && Exit 1 + chmod u+r $srcdir/$file +done + +: