This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Support cross-testing (version 3)


This third version of the cross-testing changes uses test-wrapper and
test-wrapper-env as the variables to define wrappers.  The "env"
program is only used directly in the default definition of
test-wrapper-env (so if you are testing in some way that doesn't allow
you to run that program on the host, you can define test-wrapper-env
in a different way appropriate to your test environment).

Tested x86_64 (native testing), and with cross to powerpc-linux-gnu
(testing over ssh).

2012-10-24  Joseph Myers  <joseph@codesourcery.com>
	    Jim Blandy  <jimb@codesourcery.com>

	* Makeconfig (test-wrapper): New variable,
	(test-wrapper-env): Likewise.
	[$(cross-compiling) = yes && $(test-wrapper) != ""]
	(run-built-tests): Define to yes.
	(run-program-prefix): Use $(test-wrapper).
	(built-program-cmd): Likewise.
	* Rules (make-test-out): Use $(test-wrapper-env) and
	$(host-built-program-cmd).
	* elf/Makefile ($(objpfx)order.out): Use $(test-wrapper).
	($(objpfx)tst-pathopt.out): Pass $(test-wrapper-env) to
	tst-pathopt.sh.
	($(objpfx)tst-rtld-load-self.out): Pass $(test-wrapper) and
	$(test-wrapper-env) to tst-rtld-load-self.sh.
	($(objpfx)order2.out): Use $(test-wrapper).
	($(objpfx)tst-initorder.out): Likewise.
	($(objpfx)tst-initorder2.out): Likewise.
	($(objpfx)tst-unused-dep.out): Use $(test-wrapper-env).
	* elf/tst-pathopt.sh (run_program_prefix): Remove unused variable.
	(test_wrapper_env): New variable.  Use it to run ld.so.
	* elf/tst-rtld-load-self.sh (test_wrapper): New variable.
	Use it to run ld.so.
	(test_wrapper_env): Likewise.
	* iconvdata/Makefile ($(objpfx)iconv-test.out): Pass
	$(test-wrapper) to run-iconv-test.sh.
	* iconvdata/run-iconv-test.sh (test_wrapper): New variable.
	(ICONV): Use $test_wrapper.
	* posix/Makefile ($(objpfx)globtest.out): Pass
	$(run-via-rtld-prefix), $(test-wrapper) and $(test-wrapper-env) to
	globtest.sh, not $(run-program-prefix).
	* posix/globtest.sh (run_via_rtld_prefix): New variable.
	(test_wrapper): Likewise.
	(test_wrapper_env): Likewise.  Use it to run globtest with HOME
	set together with run_via_rtld_prefix.
	(run_program_prefix): Define in terms of test_wrapper and
	run_via_rtld_prefix.
	* scripts/cross-test-ssh.sh: New file.

nptl:
2012-10-24  Joseph Myers  <joseph@codesourcery.com>
	    Jim Blandy  <jimb@codesourcery.com>

	* Makefile ($(objpfx)tst-tls6.out): Pass $(test-wrapper-env) to
	tst-tls6.sh.
	* tst-tls6.sh (test_wrapper_env): New variable.  Use it to run
	programs with LD_PRELOAD set.

diff --git a/Makeconfig b/Makeconfig
index 1b1604a..087144c 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -564,13 +564,29 @@ endif
 csu-objpfx = $(common-objpfx)csu/
 elf-objpfx = $(common-objpfx)elf/
 
+# A command that, prepended to the name and arguments of a program,
+# and run on the build system, causes that program with those
+# arguments to be run on the host for which the library is built.
+ifndef test-wrapper
+test-wrapper =
+endif
+# Likewise, but the name of the program is preceded by
+# <variable>=<value> assignments for environment variables.
+ifndef test-wrapper-env
+test-wrapper-env = $(test-wrapper) env
+endif
+
 # Whether to run test programs built for the library's host system.
 ifndef run-built-tests
 ifeq (yes,$(cross-compiling))
+ifeq (,$(test-wrapper))
 run-built-tests = no
 else
 run-built-tests = yes
 endif
+else
+run-built-tests = yes
+endif
 endif
 
 # How to run a program we just linked with our library.
@@ -600,12 +616,13 @@ endif
 # of a program built with the newly built library, produces a command
 # that, executed on the build system on which "make" is run, runs that
 # program.
-run-program-prefix = $(run-via-rtld-prefix)
+run-program-prefix = $(test-wrapper) $(run-via-rtld-prefix)
 # $(built-program-cmd) is a command that, executed on the build system
 # on which "make" is run, runs the newly built program that is the
 # second dependency of the makefile target in which
 # $(built-program-cmd) is used.
-built-program-cmd = $(run-via-rtld-prefix) $(built-program-file)
+built-program-cmd = $(test-wrapper) \
+		    $(run-via-rtld-prefix) $(built-program-file)
 # $(host-built-program-cmd) is a command that, executed on the host
 # for which the library is built, runs the newly built program that is
 # the second dependency of the makefile target in which
diff --git a/Rules b/Rules
index db5bad0..35e6ce0 100644
--- a/Rules
+++ b/Rules
@@ -180,8 +180,9 @@ ifneq "$(strip $(tests) $(xtests) $(test-srcs))" ""
 # These are the implicit rules for making test outputs
 # from the test programs and whatever input files are present.
 
-make-test-out = GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \
-		$($*-ENV) $(built-program-cmd) $($*-ARGS)
+make-test-out = $(test-wrapper-env) \
+		GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \
+		$($*-ENV) $(host-built-program-cmd) $($*-ARGS)
 $(objpfx)%-bp.out: %.input $(objpfx)%-bp
 	$(make-test-out) > $@ < $(word 1,$^)
 $(objpfx)%.out: %.input $(objpfx)%
diff --git a/elf/Makefile b/elf/Makefile
index 4f092ab..f539f13 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -644,6 +644,7 @@ $(objpfx)circlemod2a.so: $(objpfx)circlemod3a.so
 $(objpfx)order: $(addprefix $(objpfx),dep4.so dep3.so dep2.so dep1.so)
 
 $(objpfx)order.out: $(objpfx)order
+	$(test-wrapper) \
 	$(elf-objpfx)$(rtld-installed-name) \
 	  --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
 	  $(objpfx)order > $@
@@ -710,10 +711,10 @@ $(objpfx)lateglobal.out: $(objpfx)ltglobmod1.so $(objpfx)ltglobmod2.so
 $(objpfx)tst-pathopt: $(libdl)
 $(objpfx)tst-pathopt.out: tst-pathopt.sh $(objpfx)tst-pathopt \
 			  $(objpfx)pathoptobj.so
-	$(SHELL) $< $(common-objpfx)
+	$(SHELL) $< $(common-objpfx) '$(test-wrapper-env)'
 
 $(objpfx)tst-rtld-load-self.out: tst-rtld-load-self.sh $(objpfx)ld.so
-	$(SHELL) $^ > $@
+	$(SHELL) $^ '$(test-wrapper)' '$(test-wrapper-env)' > $@
 
 $(objpfx)initfirst: $(libdl)
 $(objpfx)initfirst.out: $(objpfx)firstobj.so
@@ -1035,6 +1036,7 @@ $(objpfx)tst-global1.out: $(objpfx)testobj6.so $(objpfx)testobj2.so
 $(objpfx)order2: $(libdl)
 $(objpfx)order2.out: $(objpfx)order2 $(objpfx)order2mod1.so \
 		     $(objpfx)order2mod2.so
+	$(test-wrapper) \
 	$(elf-objpfx)$(rtld-installed-name) \
 	  --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
 	  $(objpfx)order2 > $@
@@ -1129,6 +1131,7 @@ $(objpfx)tst-unique3.out: $(objpfx)tst-unique3lib2.so
 $(objpfx)tst-unique4: $(objpfx)tst-unique4lib.so
 
 $(objpfx)tst-initorder.out: $(objpfx)tst-initorder
+	$(test-wrapper) \
 	$(elf-objpfx)${rtld-installed-name} \
 	  --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
 	  $< > $@
@@ -1150,6 +1153,7 @@ object-suffixes-left := a b c d
 include $(o-iterator)
 
 $(objpfx)tst-initorder2.out: $(objpfx)tst-initorder2
+	$(test-wrapper) \
 	$(elf-objpfx)${rtld-installed-name} \
 	  --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
 	  $< > $@
@@ -1179,6 +1183,7 @@ tests: $(objpfx)tst-unused-dep.out
 endif
 
 $(objpfx)tst-unused-dep.out: $(objpfx)testobj1.so
+	$(test-wrapper-env) \
 	LD_TRACE_LOADED_OBJECTS=1 \
 	LD_DEBUG=unused \
 	LD_PRELOAD= \
diff --git a/elf/tst-pathopt.sh b/elf/tst-pathopt.sh
index 048c612..2f8bfc6 100755
--- a/elf/tst-pathopt.sh
+++ b/elf/tst-pathopt.sh
@@ -20,7 +20,7 @@
 set -e
 
 common_objpfx=$1
-run_program_prefix=$2
+test_wrapper_env=$2
 
 test -e ${common_objpfx}elf/will-be-empty &&
   rm -fr ${common_objpfx}elf/will-be-empty
@@ -29,6 +29,7 @@ test -d ${common_objpfx}elf/for-renamed ||
 
 cp ${common_objpfx}elf/pathoptobj.so ${common_objpfx}elf/for-renamed/renamed.so
 
+${test_wrapper_env} \
 LOCPATH=${common_objpfx}localedata GCONV_PATH=${common_objpfx}iconvdata \
 LC_ALL=C LD_LIBRARY_PATH=${common_objpfx}elf/will-be-empty:${common_objpfx}elf/for-renamed:${common_objpfx}.:${common_objpfx}dlfcn \
   ${common_objpfx}elf/ld.so ${common_objpfx}elf/tst-pathopt \
diff --git a/elf/tst-rtld-load-self.sh b/elf/tst-rtld-load-self.sh
index f4c5dea..18723a9 100755
--- a/elf/tst-rtld-load-self.sh
+++ b/elf/tst-rtld-load-self.sh
@@ -21,25 +21,28 @@
 set -e
 
 rtld=$1
+test_wrapper=$2
+test_wrapper_env=$3
 result=0
 
 echo '# normal mode'
-$rtld $rtld 2>&1 && rc=0 || rc=$?
+${test_wrapper} $rtld $rtld 2>&1 && rc=0 || rc=$?
 echo "# exit status $rc"
 test $rc -le 127 || result=1
 
 echo '# list mode'
-$rtld --list $rtld 2>&1 && rc=0 || rc=$?
+${test_wrapper} $rtld --list $rtld 2>&1 && rc=0 || rc=$?
 echo "# exit status $rc"
 test $rc -eq 0 || result=1
 
 echo '# verify mode'
-$rtld --verify $rtld 2>&1 && rc=0 || rc=$?
+${test_wrapper} $rtld --verify $rtld 2>&1 && rc=0 || rc=$?
 echo "# exit status $rc"
 test $rc -eq 2 || result=1
 
 echo '# trace mode'
-LD_TRACE_LOADED_OBJECTS=1 $rtld $rtld 2>&1 && rc=0 || rc=$?
+${test_wrapper_env} LD_TRACE_LOADED_OBJECTS=1 \
+    $rtld $rtld 2>&1 && rc=0 || rc=$?
 echo "# exit status $rc"
 test $rc -eq 0 || result=1
 
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
index 89f0dcd..2840cff 100644
--- a/iconvdata/Makefile
+++ b/iconvdata/Makefile
@@ -299,7 +299,7 @@ $(objpfx)tst-iconv7.out: $(objpfx)gconv-modules \
 $(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
 			 $(addprefix $(objpfx),$(modules.so)) \
 			 $(common-objdir)/iconv/iconv_prog TESTS
-	$(SHELL) $< $(common-objdir) > $@
+	$(SHELL) $< $(common-objdir) '$(test-wrapper)' > $@
 
 $(objpfx)tst-tables.out: tst-tables.sh $(objpfx)gconv-modules \
 			 $(addprefix $(objpfx),$(modules.so)) \
diff --git a/iconvdata/run-iconv-test.sh b/iconvdata/run-iconv-test.sh
index cb9f5df..ec8f024 100755
--- a/iconvdata/run-iconv-test.sh
+++ b/iconvdata/run-iconv-test.sh
@@ -21,6 +21,7 @@
 set -e
 
 codir=$1
+test_wrapper="$2"
 
 # We use always the same temporary file.
 temp1=$codir/iconvdata/iconv-test.xxx
@@ -39,6 +40,7 @@ LIBPATH=$codir:$codir/iconvdata
 # How the start the iconv(1) program.
 ICONV='$codir/elf/ld.so --library-path $LIBPATH --inhibit-rpath ${from}.so \
        $codir/iconv/iconv_prog'
+ICONV="$test_wrapper $ICONV"
 
 # Which echo?
 if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
diff --git a/nptl/Makefile b/nptl/Makefile
index 21a8766..fc71177 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -476,7 +476,7 @@ $(objpfx)tst-tls6.out: tst-tls6.sh $(objpfx)tst-tls5 \
 		       $(objpfx)tst-tls5modc.so $(objpfx)tst-tls5modd.so \
 		       $(objpfx)tst-tls5mode.so $(objpfx)tst-tls5modf.so
 	$(SHELL) $< $(common-objpfx) $(elf-objpfx) \
-		    $(rtld-installed-name)
+		    $(rtld-installed-name) '$(test-wrapper-env)'
 endif
 
 $(objpfx)tst-dlsym1: $(libdl) $(shared-thread-library)
diff --git a/nptl/tst-tls6.sh b/nptl/tst-tls6.sh
index 2622e33..6ef1232 100755
--- a/nptl/tst-tls6.sh
+++ b/nptl/tst-tls6.sh
@@ -22,6 +22,7 @@ set -e
 common_objpfx=$1; shift
 elf_objpfx=$1; shift
 rtld_installed_name=$1; shift
+test_wrapper_env=$1; shift
 logfile=$common_objpfx/nptl/tst-tls6.out
 
 # We have to find libc and nptl
@@ -40,33 +41,38 @@ fail=0
 for aligned in a e f; do
   echo "preload tst-tls5mod{$aligned,b,c,d}.so" >> $logfile
   echo "===============" >> $logfile
-  LD_PRELOAD=`echo ${common_objpfx}nptl/tst-tls5mod{$aligned,b,c,d}.so \
-	      | sed 's/:$//;s/: /:/g'` ${tst_tls5} >> $logfile || fail=1
+  ${test_wrapper_env} \
+  LD_PRELOAD="`echo ${common_objpfx}nptl/tst-tls5mod{$aligned,b,c,d}.so \
+	      | sed 's/:$//;s/: /:/g'`" ${tst_tls5} >> $logfile || fail=1
   echo >> $logfile
 
   echo "preload tst-tls5mod{b,$aligned,c,d}.so" >> $logfile
   echo "===============" >> $logfile
-  LD_PRELOAD=`echo ${common_objpfx}nptl/tst-tls5mod{b,$aligned,c,d}.so \
-	      | sed 's/:$//;s/: /:/g'` ${tst_tls5} >> $logfile || fail=1
+  ${test_wrapper_env} \
+  LD_PRELOAD="`echo ${common_objpfx}nptl/tst-tls5mod{b,$aligned,c,d}.so \
+	      | sed 's/:$//;s/: /:/g'`" ${tst_tls5} >> $logfile || fail=1
   echo >> $logfile
 
   echo "preload tst-tls5mod{b,c,d,$aligned}.so" >> $logfile
   echo "===============" >> $logfile
-  LD_PRELOAD=`echo ${common_objpfx}nptl/tst-tls5mod{b,c,d,$aligned}.so \
-	      | sed 's/:$//;s/: /:/g'` ${tst_tls5} >> $logfile || fail=1
+  ${test_wrapper_env} \
+  LD_PRELOAD="`echo ${common_objpfx}nptl/tst-tls5mod{b,c,d,$aligned}.so \
+	      | sed 's/:$//;s/: /:/g'`" ${tst_tls5} >> $logfile || fail=1
   echo >> $logfile
 done
 
 echo "preload tst-tls5mod{d,a,b,c,e}" >> $logfile
 echo "===============" >> $logfile
-LD_PRELOAD=`echo ${common_objpfx}nptl/tst-tls5mod{d,a,b,c,e}.so \
-	    | sed 's/:$//;s/: /:/g'` ${tst_tls5} >> $logfile || fail=1
+${test_wrapper_env} \
+LD_PRELOAD="`echo ${common_objpfx}nptl/tst-tls5mod{d,a,b,c,e}.so \
+	    | sed 's/:$//;s/: /:/g'`" ${tst_tls5} >> $logfile || fail=1
 echo >> $logfile
 
 echo "preload tst-tls5mod{d,a,b,e,f}" >> $logfile
 echo "===============" >> $logfile
-LD_PRELOAD=`echo ${common_objpfx}nptl/tst-tls5mod{d,a,b,e,f}.so \
-	    | sed 's/:$//;s/: /:/g'` ${tst_tls5} >> $logfile || fail=1
+${test_wrapper_env} \
+LD_PRELOAD="`echo ${common_objpfx}nptl/tst-tls5mod{d,a,b,e,f}.so \
+	    | sed 's/:$//;s/: /:/g'`" ${tst_tls5} >> $logfile || fail=1
 echo >> $logfile
 
 exit $fail
diff --git a/posix/Makefile b/posix/Makefile
index 86e6c6b..328738d 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -117,7 +117,8 @@ ifeq ($(run-built-tests),yes)
 ifeq (yes,$(build-shared))
 tests: $(objpfx)globtest.out $(objpfx)wordexp-tst.out
 $(objpfx)globtest.out: globtest.sh $(objpfx)globtest
-	$(SHELL) $< $(common-objpfx) '$(run-program-prefix)'
+	$(SHELL) $< $(common-objpfx) '$(run-via-rtld-prefix)' \
+		'$(test-wrapper)' '$(test-wrapper-env)'
 $(objpfx)wordexp-tst.out: wordexp-tst.sh $(objpfx)wordexp-test
 	$(SHELL) $< $(common-objpfx) '$(run-program-prefix)'
 endif
diff --git a/posix/globtest.sh b/posix/globtest.sh
index ea947b8..121be85 100755
--- a/posix/globtest.sh
+++ b/posix/globtest.sh
@@ -20,7 +20,10 @@
 set -e
 
 common_objpfx=$1; shift
-run_program_prefix=$1; shift
+run_via_rtld_prefix=$1; shift
+test_wrapper=$1; shift
+test_wrapper_env=$1; shift
+run_program_prefix="${test_wrapper} ${run_via_rtld_prefix}"
 logfile=$common_objpfx/posix/globtest.out
 
 #CMP=cmp
@@ -758,8 +761,9 @@ cat <<"EOF" | $CMP - $testout >> $logfile || failed=1
 `dir6/file1[ab]'
 `nondir\/'
 EOF
+${test_wrapper_env} \
 HOME="$testdir" \
-${run_program_prefix} \
+${run_via_rtld_prefix} \
 ${common_objpfx}posix/globtest -ct "$testdir" \
 '~/dir1/file1_1' '~/dir1/file1_9' '~/dir3\*/file1' '~/dir3\*/file2' \
 '~\/dir1/file1_2' |
diff --git a/scripts/cross-test-ssh.sh b/scripts/cross-test-ssh.sh
new file mode 100755
index 0000000..5dd3be4
--- /dev/null
+++ b/scripts/cross-test-ssh.sh
@@ -0,0 +1,156 @@
+#! /bin/bash
+# Run a testcase on a remote system, via ssh.
+# Copyright (C) 2012 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library 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
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+# usage: cross-test-ssh.sh [--ssh SSH] HOST COMMAND ...
+# Run with --help flag to get more detailed help.
+
+progname="$(basename $0)"
+env_blacklist='HOME LOGNAME MAIL PATH SHELL SHLVL SSH_CLIENT SSH_CONNECTION
+USER TERM TERMCAP PWD'
+
+usage="usage: ${progname} [--ssh SSH] HOST COMMAND ..."
+help="Run a glibc test COMMAND on the remote machine HOST, via ssh,
+passing environment variables, preserving the current working directory,
+and respecting quoting.
+
+If the '--ssh SSH' flag is present, use SSH as the SSH command,
+instead of ordinary 'ssh'.
+
+To use this to run glibc tests, invoke the tests as follows:
+
+  $ make test-wrapper='ABSPATH/cross-test-ssh.sh HOST' tests
+
+where ABSPATH is the absolute path to this script, and HOST is the
+name of the machine to connect to via ssh.
+
+If you need to connect to the test machine as a different user, you
+may specify that just as you would to SSH:
+
+  $ make test-wrapper='ABSPATH/cross-test-ssh.sh USER@HOST' tests
+
+Naturally, the remote user must have an appropriate public key, and
+you will want to ensure that SSH does not prompt interactively for a
+password on each connection.
+
+HOST and the build machines (on which 'make check' is being run) must
+share a filesystem; all files needed by the tests must be visible at
+the same paths on both machines.
+
+${progname} runs COMMAND in the same directory on the HOST that
+${progname} itself is run in on the build machine.
+
+The command and arguments are passed to the remote host in a way that
+avoids any further shell substitution or expansion, on the assumption
+that the shell on the build machine has already done them
+appropriately.
+
+${progname} propagates the values all environment variables through to
+the remote target, except the following:
+${env_blacklist}"
+
+ssh='ssh'
+while true; do
+    case "$1" in
+
+        "--ssh")
+            shift; ssh="$1"
+            ;;
+
+        "--help")
+            echo "$usage"
+            echo "$help"
+            exit 0
+            ;;
+
+        *)
+            break
+            ;;
+    esac
+    shift
+done
+
+if [ $# -lt 1 ]; then
+    echo "$usage" >&2
+    echo "Type '${progname} --help' for more detailed help." >&2
+    exit 1
+fi
+
+host="$1"; shift
+
+# Return all input as a properly quoted Bourne shell string.
+bourne_quote ()
+{
+    printf '%s' '"'
+    sed -n \
+        -e '1h' \
+        -e '2,$H' \
+        -e '${g
+              s/["$\`]/\\&/g
+              p
+             }'
+    printf '%s' '"'
+}
+
+# Remove unnecessary newlines from a Bourne shell command sequence.
+remove_newlines ()
+{
+    sed -n \
+        -e '1h' \
+        -e '2,$H' \
+        -e '${g
+              s/\([^\]\)\n/\1; /g
+              p
+             }'
+}
+
+# Unset all variables from the blacklist.  Then echo all exported
+# variables.  This should be run in a subshell.  The 'export -p'
+# command adds backslashes for environment variables which contain
+# newlines.
+blacklist_exports ()
+{
+    local var
+    for var in ${env_blacklist}; do
+	unset $var
+    done
+    export -p
+}
+
+# Produce properly quoted Bourne shell arguments for 'env' to carry
+# over the current environment, less blacklisted variables.
+exports="$( (blacklist_exports) | sed -e 's|^declare -x |export |')"
+
+# Transform the current argument list into a properly quoted Bourne shell
+# command string.
+command="$(for word in "$@"; do
+               printf '%s' "$word" | bourne_quote
+               printf '%s' ' '
+           done)"
+
+# Add commands to set environment variables and the current directory.
+command="${exports}
+cd $PWD
+${command}"
+
+# HOST's sshd simply concatenates its arguments with spaces and
+# passes them to some shell.  We want to force the use of /bin/sh,
+# so we need to re-quote the whole command to ensure it appears as
+# the sole argument of the '-c' option.
+full_command="$(printf '%s\n' "${command}" | bourne_quote | remove_newlines)"
+$ssh "$host" /bin/sh -c "$full_command"

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]