[[[
Allow testing of application exit codes.

This makes all of the lower-level process-running functions in
cmdline/svntest/main.py and cmdline/svntest/actions.py return
the exit code, all of the "run_and_verify_*()" functions guess the
expected exit code based on whether or not output on stderr is
expected, and new "run_and_verify_*2()" functions allow the 
expected exit code to be provided explicitly.

On platforms without the Popen3 Python class (e.g. Windows), exit
codes are returned as None, and therefore disregarded during
validation.


* subversion/tests/cmdline/svntest/main.py
 (run_command, run_svn, run_svnadmin, run_svnlook, run_svnsync,
  run_svnversion, run_command_stdin):
  Include exit_code in the returned tuple.

 (create_repos): Accept exit_code returned from run_command.

 (run_one): Clarify a comment concerning exit codes

* subversion/tests/cmdline/svntest/actions.py
 (run_and_verify_svnlook2, run_and_verify_svnadmin2,
  run_and_verify_svnversion2, run_and_verify_svn2,
  run_and_verify_svn_match_any2): New, execute the indicated binary
  and check actual outputs and exit code against the expected value
  parameters.

 (run_and_verify_svnlook, run_and_verify_svnadmin,
  run_and_verify_svnversion, run_and_verify_svn,
  run_and_verify_svn_match_any): Guess whether the expected exit should
  be 0 or 1 based on whether output is expected on stderr.  Then invoke
  the coresponding run_and_verify_*2 function with that value.  Return
  exit_code, stdout_lines, stderr_lines.

 (setup_pristine_repository, run_and_verify_load, run_and_verify_dump,
  run_and_verify_checkout, run_and_verify_update, run_and_verify_commit,
  run_and_verify_status, run_and_verify_unquiet_status,
  run_and_verify_diff_summarize, run_and_verify_diff_summarize_xml,
  run_and_verify_log_xml, run_and_verify_merge2,
  run_and_verify_mergeinfo, run_and_verify_switch, run_and_validate_lock,
  check_prop, inject_conflict_into_wc, run_and_verify_export):
  Accept exit_code value returned from main.run_svn, main.run_command,
  main.run_svnadmin, main.run_command_stdin, actions.run_and_verify_svn

* subversion/tests/cmdline/svntest/tree.py
 (get_props): Accept exit code returned by main.run_svn.

* subversion/tests/cmdline/svntest/verify.py
 (SVNUnexpectedExitCode): New exception raised when the exit code was not
  what was expected.

 (verify_exit_code): New, compares expected and actual exit code and raises
  an exception if they are different.  Comparison is not performed if expected
  exit code is None.

* subversion/tests/cmdline/cat_tests.py,
  subversion/tests/cmdline/lock_tests.py,
  subversion/tests/cmdline/stat_tests.py:
  Accept exit code returned from run_*(), replacing those calls with the
  run_*2() counterparts for cases where stderr output is produced while
  exiting 0.

* subversion/tests/cmdline/prop_tests.py: 
  Accept exit code returned from the run_*() function calls, and verify
  exit codes along with each verify_output().
 
* subversion/tests/cmdline/authz_tests.py,
  subversion/tests/cmdline/autoprop_tests.py,
  subversion/tests/cmdline/basic_tests.py,
  subversion/tests/cmdline/blame_tests.py,
  subversion/tests/cmdline/changelist_tests.py,
  subversion/tests/cmdline/checkout_tests.py,
  subversion/tests/cmdline/commit_tests.py,
  subversion/tests/cmdline/copy_tests.py,
  subversion/tests/cmdline/depth_tests.py,
  subversion/tests/cmdline/diff_tests.py,
  subversion/tests/cmdline/getopt_tests.py,
  subversion/tests/cmdline/import_tests.py,
  subversion/tests/cmdline/log_tests.py,
  subversion/tests/cmdline/merge_tests.py,
  subversion/tests/cmdline/revert_tests.py,
  subversion/tests/cmdline/schedule_tests.py,
  subversion/tests/cmdline/special_tests.py,
  subversion/tests/cmdline/svnadmin_tests.py,
  subversion/tests/cmdline/svndumpfilter_tests.py,
  subversion/tests/cmdline/svnlook_tests.py,
  subversion/tests/cmdline/svnsync_tests.py,
  subversion/tests/cmdline/svnversion_tests.py,
  subversion/tests/cmdline/switch_tests.py,
  subversion/tests/cmdline/update_tests.py:
  Accept exit code returned from the run_*() function calls.

]]]


Index: subversion/tests/cmdline/svntest/tree.py
===================================================================
--- subversion/tests/cmdline/svntest/tree.py	(revision 29740)
+++ subversion/tests/cmdline/svntest/tree.py	(working copy)
@@ -321,7 +321,7 @@
   # respecting the black-box paradigm.
 
   props = {}
-  output, errput = main.run_svn(1, "proplist", path, "--verbose")
+  exit_code, output, errput = main.run_svn(1, "proplist", path, "--verbose")
 
   first_value = 0
   for line in output:
Index: subversion/tests/cmdline/svntest/actions.py
===================================================================
--- subversion/tests/cmdline/svntest/actions.py	(revision 29740)
+++ subversion/tests/cmdline/svntest/actions.py	(working copy)
@@ -54,9 +54,10 @@
     # import the greek tree, using l:foo/p:bar
     ### todo: svn should not be prompting for auth info when using
     ### repositories with no auth/auth requirements
-    output, errput = main.run_svn(None, 'import',
-                                  '-m', 'Log message for revision 1.',
-                                  main.greek_dump_dir, main.pristine_url)
+    exit_code, output, errput = main.run_svn(None, 'import', '-m',
+                                             'Log message for revision 1.',
+                                             main.greek_dump_dir,
+                                             main.pristine_url)
 
     # check for any errors from the import
     if len(errput):
@@ -119,34 +120,100 @@
 
 def run_and_verify_svnlook(message, expected_stdout,
                            expected_stderr, *varargs):
-  "Run svnlook command and check its output"
-  out, err = main.run_svnlook(*varargs)
+  """Like run_and_verify_svnlook2, but the expected exit code is
+  assumed to be 0 if no output is expected on stderr, and 1 otherwise.
+  
+  Exit code is not checked on platforms without Popen3 - see note in
+  run_and_verify_svn2."""
+  expected_exit = 0
+  if expected_stderr is not None and expected_stderr != []:
+    expected_exit = 1
+  return run_and_verify_svnlook2(message, expected_stdout, expected_stderr, 
+                                 expected_exit, *varargs)
+
+def run_and_verify_svnlook2(message, expected_stdout, expected_stderr, 
+                            expected_exit, *varargs):
+  """Run svnlook command and check its output and exit code.
+  
+  Exit code is not checked on platforms without Popen3 - see note in
+  run_and_verify_svn2."""
+  exit_code, out, err = main.run_svnlook(*varargs)
   verify.verify_outputs("Unexpected output", out, err,
                         expected_stdout, expected_stderr)
-  return out, err
+  verify.verify_exit_code(message, exit_code, expected_exit)
+  return exit_code, out, err
 
 
 def run_and_verify_svnadmin(message, expected_stdout,
                             expected_stderr, *varargs):
-  "Run svnadmin command and check its output"
-  out, err = main.run_svnadmin(*varargs)
+  """Like run_and_verify_svnadmin2, but the expected exit code is
+  assumed to be 0 if no output is expected on stderr, and 1 otherwise.
+
+  Exit code is not checked on platforms without Popen3 - see note in
+  run_and_verify_svn2."""
+  expected_exit = 0
+  if expected_stderr is not None and expected_stderr != []:
+    expected_exit = 1
+  return run_and_verify_svnadmin2(message, expected_stdout, expected_stderr, 
+                                  expected_exit, *varargs)
+
+def run_and_verify_svnadmin2(message, expected_stdout, expected_stderr, 
+                             expected_exit, *varargs):
+  """Run svnadmin command and check its output and exit code.
+  
+  Exit code is not checked on platforms without Popen3 - see note in
+  run_and_verify_svn2."""
+  exit_code, out, err = main.run_svnadmin(*varargs)
   verify.verify_outputs("Unexpected output", out, err,
                         expected_stdout, expected_stderr)
-  return out, err
+  verify.verify_exit_code(message, exit_code, expected_exit)
+  return exit_code, out, err
 
 
 def run_and_verify_svnversion(message, wc_dir, repo_url,
                               expected_stdout, expected_stderr):
-  "Run svnversion command and check its output"
-  out, err = main.run_svnversion(wc_dir, repo_url)
+  """like run_and_verify_svnversion2, but the expected exit code is
+  assumed to be 0 if no output is expected on stderr, and 1 otherwise.
+
+  Exit code is not checked on platforms without Popen3 - see note in
+  run_and_verify_svn2."""
+  expected_exit = 0
+  if expected_stderr is not None and expected_stderr != []:
+    expected_exit = 1
+  return run_and_verify_svnversion2(message, wc_dir, repo_url,
+                                    expected_stdout, expected_stderr,
+                                    expected_exit)
+
+def run_and_verify_svnversion2(message, wc_dir, repo_url,
+                               expected_stdout, expected_stderr,
+                               expected_exit):
+  """Run svnversion command and check its output and exit code.
+  
+  Exit code is not checked on platforms without Popen3 - see note in
+  run_and_verify_svn2."""
+  exit_code, out, err = main.run_svnversion(wc_dir, repo_url)
   verify.verify_outputs("Unexpected output", out, err,
                         expected_stdout, expected_stderr)
-  return out, err
+  verify.verify_exit_code(message, exit_code, expected_exit)
+  return exit_code, out, err
 
+def run_and_verify_svn(message, expected_stdout, expected_stderr, *varargs):
+  """like run_and_verify_svn2, but the expected exit code is assumed to
+  be 0 if no output is expected on stderr, and 1 otherwise.
+  
+  Exit code is not checked on platforms without Popen3 - see note in
+  run_and_verify_svn2."""
 
-def run_and_verify_svn(message, expected_stdout, expected_stderr, *varargs):
-  """Invokes main.run_svn() with *VARARGS, return stdout and stderr as
-  lists of lines.  For both EXPECTED_STDOUT and EXPECTED_STDERR,
+  expected_exit = 0
+  if expected_stderr is not None and expected_stderr != []:
+    expected_exit = 1
+  return run_and_verify_svn2(message, expected_stdout, expected_stderr,
+                             expected_exit, *varargs)
+
+def run_and_verify_svn2(message, expected_stdout, expected_stderr,
+                        expected_exit, *varargs):
+  """Invokes main.run_svn() with *VARARGS, returns exit code as int, stdout
+  and stderr as lists of lines.  For both EXPECTED_STDOUT and EXPECTED_STDERR,
   create an appropriate instance of verify.ExpectedOutput (if necessary):
 
      - If it is an array of strings, create a vanilla ExpectedOutput.
@@ -163,6 +230,11 @@
   If EXPECTED_STDOUT is None, do not check stdout.
   EXPECTED_STDERR may not be None.
 
+  If output checks pass, on supported platforms (namely those with the Popen3
+  class), the expected and actual codes are compared.  On platforms lacking
+  Popen3, the actual exit code is unavailable and a value of None is returned
+  as the exit code from this and all other run_...() functions.
+
   If a comparison fails, a Failure will be raised."""
 
   if expected_stderr is None:
@@ -172,15 +244,34 @@
   if expected_stderr is not None and expected_stderr != []:
     want_err = True
 
-  out, err = main.run_svn(want_err, *varargs)
+  exit_code, out, err = main.run_svn(want_err, *varargs)
   verify.verify_outputs(message, out, err, expected_stdout, expected_stderr)
-  return out, err
+  verify.verify_exit_code(message, exit_code, expected_exit)
+  return exit_code, out, err
 
 def run_and_verify_svn_match_any(message, expected_stdout, expected_stderr,
                                  *varargs):
-  """Like run_and_verify_svn, except that only one stdout line must match
-  EXPECTED_STDOUT."""
+  """Like run_and_verify_svn_match_any2, but the expected exit code is
+  assumed to be 0 if no output is expected on stderr, and 1 otherwise.
 
+  Exit code is not checked on platforms without Popen3 - see note in
+  run_and_verify_svn2."""
+  expected_exit = 0
+  if expected_stderr is not None and expected_stderr != []:
+    expected_exit = 1
+  return run_and_verify_svn_match_any2(message, expected_stdout,
+                                       expected_stderr, expected_exit,
+                                       *varargs)
+                                 
+
+def run_and_verify_svn_match_any2(message, expected_stdout, expected_stderr,
+                                 expected_exit, *varargs):
+  """Like run_and_verify_svn2, except that only one stdout line must match
+  EXPECTED_STDOUT.
+
+  Exit code is not checked on platforms without Popen3 - see note in
+  run_and_verify_svn2."""
+
   if expected_stderr is None:
     raise verify.SVNIncorrectDatatype("expected_stderr must not be None")
 
@@ -188,26 +279,27 @@
   if expected_stderr is not None and expected_stderr != []:
     want_err = True
 
-  out, err = main.run_svn(want_err, *varargs)
+  exit_code, out, err = main.run_svn(want_err, *varargs)
   verify.verify_outputs(message, out, err, expected_stdout, expected_stderr,
                         False)
-  return out, err
+  verify.verify_exit_code(message, exit_code, expected_exit)
+  return exit_code, out, err
 
 
 def run_and_verify_load(repo_dir, dump_file_content):
   "Runs 'svnadmin load' and reports any errors."
   expected_stderr = []
-  output, errput = \
-          main.run_command_stdin(main.svnadmin_binary,
-    expected_stderr, 1, dump_file_content,
+  exit_code, output, errput = main.run_command_stdin(
+    main.svnadmin_binary, expected_stderr, 1, dump_file_content,
     'load', '--force-uuid', '--quiet', repo_dir)
+
   verify.verify_outputs("Unexpected stderr output", None, errput,
                         None, expected_stderr)
 
 
 def run_and_verify_dump(repo_dir):
   "Runs 'svnadmin dump' and reports any errors, returning the dump content."
-  output, errput = main.run_svnadmin('dump', repo_dir)
+  exit_code, output, errput = main.run_svnadmin('dump', repo_dir)
   verify.verify_outputs("Missing expected output(s)", output, errput,
                         verify.AnyOutput, verify.AnyOutput)
   return output
@@ -281,8 +373,8 @@
   # Checkout and make a tree of the output, using l:foo/p:bar
   ### todo: svn should not be prompting for auth info when using
   ### repositories with no auth/auth requirements
-  output, errput = main.run_svn (None, 'co',
-                                 URL, wc_dir_name, *args)
+  exit_code, output, errput = main.run_svn(None, 'co',
+                                           URL, wc_dir_name, *args)
   actual = tree.build_tree_from_checkout (output)
 
   # Verify actual output against expected output.
@@ -320,8 +412,8 @@
   # Export and make a tree of the output, using l:foo/p:bar
   ### todo: svn should not be prompting for auth info when using
   ### repositories with no auth/auth requirements
-  output, errput = main.run_svn (None, 'export',
-                                 URL, export_dir_name, *args)
+  exit_code, output, errput = main.run_svn(None, 'export',
+                                           URL, export_dir_name, *args)
   actual = tree.build_tree_from_checkout (output)
 
   # Verify actual output against expected output.
@@ -472,7 +564,7 @@
   if expected_paths != None:
     log_args.append('-v')
 
-  (stdout, stderr) = run_and_verify_svn(
+  (exit_code, stdout, stderr) = run_and_verify_svn(
     message, expected_stdout, expected_stderr,
     'log', '--xml', *log_args)
   if not parse:
@@ -590,9 +682,11 @@
 
   # Update and make a tree of the output.
   if len(args):
-    output, errput = main.run_svn (error_re_string, 'up', *args)
+    exit_code, output, errput = main.run_svn(error_re_string, 'up', *args)
   else:
-    output, errput = main.run_svn (error_re_string, 'up', wc_dir_name, *args)
+    exit_code, output, errput = main.run_svn(error_re_string,
+                                             'up', wc_dir_name,
+                                             *args)
 
   if (error_re_string):
     rm = re.compile(error_re_string)
@@ -694,7 +788,8 @@
     pre_disk = tree.build_tree_from_wc(dir)
     dry_run_command = merge_command + ('--dry-run',)
     dry_run_command = dry_run_command + args
-    out_dry, err_dry = main.run_svn(error_re_string, *dry_run_command)
+    exit_code, out_dry, err_dry = main.run_svn(error_re_string,
+                                               *dry_run_command)
     post_disk = tree.build_tree_from_wc(dir)
     try:
       tree.compare_trees("disk", post_disk, pre_disk)
@@ -707,7 +802,7 @@
 
   # Update and make a tree of the output.
   merge_command = merge_command + args
-  out, err = main.run_svn (error_re_string, *merge_command)
+  exit_code, out, err = main.run_svn(error_re_string, *merge_command)
 
   if error_re_string:
     if not error_re_string.startswith(".*"):
@@ -761,7 +856,7 @@
 
   mergeinfo_command = ["mergeinfo"]
   mergeinfo_command.extend(args)
-  out, err = main.run_svn(error_re_string, *mergeinfo_command)
+  exit_code, out, err = main.run_svn(error_re_string, *mergeinfo_command)
 
   if error_re_string:
     if not error_re_string.startswith(".*"):
@@ -841,8 +936,8 @@
     status_tree = status_tree.old_tree()
 
   # Update and make a tree of the output.
-  output, errput = main.run_svn (error_re_string, 'switch',
-                                 switch_url, wc_target, *args)
+  exit_code, output, errput = main.run_svn(error_re_string, 'switch',
+                                           switch_url, wc_target, *args)
 
   if error_re_string:
     if not error_re_string.startswith(".*"):
@@ -885,9 +980,9 @@
     status_tree = status_tree.old_tree()
 
   # Commit.
-  output, errput = main.run_svn(error_re_string, 'ci',
-                                '-m', 'log msg',
-                                *args)
+  exit_code, output, errput = main.run_svn(error_re_string, 'ci',
+                                           '-m', 'log msg',
+                                           *args)
 
   if error_re_string:
     if not error_re_string.startswith(".*"):
@@ -957,8 +1052,8 @@
   if isinstance(output_tree, wc.State):
     output_tree = output_tree.old_tree()
 
-  output, errput = main.run_svn (None, 'status', '-v', '-u', '-q',
-                                 wc_dir_name)
+  exit_code, output, errput = main.run_svn(None, 'status', '-v', '-u', '-q',
+                                           wc_dir_name)
 
   actual = tree.build_tree_from_status (output)
 
@@ -988,7 +1083,8 @@
   if isinstance(output_tree, wc.State):
     output_tree = output_tree.old_tree()
 
-  output, errput = main.run_svn (None, 'status', '-v', '-u', wc_dir_name)
+  exit_code, output, errput = main.run_svn(None, 'status', '-v',
+                                           '-u', wc_dir_name)
 
   actual = tree.build_tree_from_status (output)
 
@@ -1022,8 +1118,10 @@
   EXPECTED_PROPS and EXPECTED_KINDS. Returns on success, raises
   on failure."""
 
-  output, errput = run_and_verify_svn(None, None, error_re_string, 'diff',
-                                      '--summarize', '--xml', *args)
+  exit_code, output, errput = run_and_verify_svn(None, None, error_re_string,
+                                                 'diff', '--summarize',
+                                                 '--xml', *args)
+                                      
 
   # Return if errors are present since they were expected
   if len(errput) > 0:
@@ -1092,8 +1190,8 @@
   if isinstance(output_tree, wc.State):
     output_tree = output_tree.old_tree()
 
-  output, errput = main.run_svn (None, 'diff', '--summarize',
-                                 *args)
+  exit_code, output, errput = main.run_svn(None, 'diff', '--summarize',
+                                           *args)
 
   if error_re_string:
     if not error_re_string.startswith(".*"):
@@ -1126,9 +1224,9 @@
                      '-m', comment, path)
 
   # Run info and check that we get the lock fields.
-  output, err = run_and_verify_svn(None, None, [],
-                                   'info','-R',
-                                   path)
+  exit_code, output, err = run_and_verify_svn(None, None, [],
+                                              'info','-R',
+                                              path)
 
   ### TODO: Leverage RegexOuput([...], match_all=True) here.
   # prepare the regexs to compare against
@@ -1271,9 +1369,10 @@
 def check_prop(name, path, exp_out):
   """Verify that property NAME on PATH has a value of EXP_OUT"""
   # Not using run_svn because binary_mode must be set
-  out, err = main.run_command(main.svn_binary, None, 1, 'pg', '--strict',
-                              name, path, '--config-dir',
-                              main.default_config_dir)
+  exit_code, out, err = main.run_command(main.svn_binary, None, 1, 'pg',
+                                         '--strict', name, path,
+                                         '--config-dir',
+                                         main.default_config_dir)
   if out != exp_out:
     print "svn pg --strict", name, "output does not match expected."
     print "Expected standard output: ", exp_out, "\n"
@@ -1327,8 +1426,8 @@
                         None, file_path)
 
   # Backdate the file.
-  output, errput = main.run_svn(None, "up", "-r", str(prev_rev),
-                                 file_path)
+  exit_code, output, errput = main.run_svn(None, "up", "-r", str(prev_rev),
+                                           file_path)
   if expected_status:
     expected_status.tweak(state_path, wc_rev=prev_rev)
 
@@ -1346,8 +1445,9 @@
                                       expected_disk, expected_status,
                                       conflicting_contents, contents,
                                       merged_rev)
-  output, errput = main.run_svn(None, "up", "-r", str(merged_rev),
-                                sbox.repo_url + "/" + state_path, file_path)
+  exit_code, output, errput = main.run_svn(None, "up", "-r", str(merged_rev),
+                                           sbox.repo_url + "/" + state_path,
+                                           file_path)
   if expected_status:
     expected_status.tweak(state_path, wc_rev=merged_rev)
 
Index: subversion/tests/cmdline/svntest/main.py
===================================================================
--- subversion/tests/cmdline/svntest/main.py	(revision 29740)
+++ subversion/tests/cmdline/svntest/main.py	(working copy)
@@ -304,9 +304,10 @@
 
   return os.path.join(repo_dir, "conf", "svnserve.conf")
 
-# Run any binary, logging the command line (TODO: and return code)
+# Run any binary, logging the command line and return code
 def run_command(command, error_expected, binary_mode=0, *varargs):
-  """Run COMMAND with VARARGS; return stdout, stderr as lists of lines.
+  """Run COMMAND with VARARGS; return exit code as int; stdout, stderr
+  as lists of lines.
   If ERROR_EXPECTED is None, any stderr also will be printed."""
 
   return run_command_stdin(command, error_expected, binary_mode,
@@ -415,7 +416,7 @@
   should not be very large, as if the program outputs more than the OS
   is willing to buffer, this will deadlock, with both Python and
   COMMAND waiting to write to each other for ever.
-  Return stdout, stderr as lists of lines.
+  Return exit code as int; stdout, stderr as lists of lines.
   If ERROR_EXPECTED is None, any stderr also will be printed."""
 
   if verbose_mode:
@@ -434,7 +435,7 @@
     map(sys.stdout.write, stderr_lines)
     raise Failure
 
-  return stdout_lines, stderr_lines
+  return exit_code, stdout_lines, stderr_lines
 
 def create_config_dir(cfgdir, config_contents=None, server_contents=None):
   "Create config directories and files"
@@ -486,7 +487,8 @@
 
 # For running subversion and returning the output
 def run_svn(error_expected, *varargs):
-  """Run svn with VARARGS; return stdout, stderr as lists of lines.
+  """Run svn with VARARGS; return exit code as int; stdout, stderr as
+  lists of lines.
   If ERROR_EXPECTED is None, any stderr also will be printed.  If
   you're just checking that something does/doesn't come out of
   stdout/stderr, you might want to use actions.run_and_verify_svn()."""
@@ -495,20 +497,24 @@
 
 # For running svnadmin.  Ignores the output.
 def run_svnadmin(*varargs):
-  "Run svnadmin with VARARGS, returns stdout, stderr as list of lines."
+  """Run svnadmin with VARARGS, returns exit code as int; stdout, stderr as
+  list of lines."""
   return run_command(svnadmin_binary, 1, 0, *varargs)
 
 # For running svnlook.  Ignores the output.
 def run_svnlook(*varargs):
-  "Run svnlook with VARARGS, returns stdout, stderr as list of lines."
+  """Run svnlook with VARARGS, returns exit code as int; stdout, stderr as
+  list of lines."""
   return run_command(svnlook_binary, 1, 0, *varargs)
 
 def run_svnsync(*varargs):
-  "Run svnsync with VARARGS, returns stdout, stderr as list of lines."
+  """Run svnsync with VARARGS, returns exit code as int; stdout, stderr as
+  list of lines."""
   return run_command(svnsync_binary, 1, 0, *(_with_config_dir(varargs)))
 
 def run_svnversion(*varargs):
-  "Run svnversion with VARARGS, returns stdout, stderr as list of lines."
+  """Run svnversion with VARARGS, returns exit code as int; stdout, stderr
+  as list of lines."""
   return run_command(svnversion_binary, 1, 0, *varargs)
 
 # Chmod recursively on a whole subtree
@@ -595,7 +601,8 @@
     opts += ("--pre-1.5-compatible",)
   if fs_type is not None:
     opts += ("--fs-type=" + fs_type,)
-  stdout, stderr = run_command(svnadmin_binary, 1, 0, "create", path, *opts)
+  exit_code, stdout, stderr = run_command(svnadmin_binary, 1, 0, "create",
+                                          path, *opts)
 
   # Skip tests if we can't create the repository.
   if stderr:
@@ -1006,7 +1013,7 @@
       args.append('--server-minor-version=' + str(server_minor_version))
 
     result, stdout_lines, stderr_lines = spawn_process(command, 1, None, *args)
-    # don't trust the exitcode, will not be correct on Windows
+    # "result" will be None on platforms without Popen3 (e.g. Windows)
     if filter(lambda x: x.startswith('FAIL: ') or x.startswith('XPASS: '),
               stdout_lines):
       result = 1
Index: subversion/tests/cmdline/svntest/verify.py
===================================================================
--- subversion/tests/cmdline/svntest/verify.py	(revision 29740)
+++ subversion/tests/cmdline/svntest/verify.py	(working copy)
@@ -49,6 +49,11 @@
   STDERR when output was expected."""
   pass
 
+class SVNUnexpectedExitCode(SVNUnexpectedOutput):
+  """Exception raised if an invocation of svn exits with a value other
+  than what was expected."""
+  pass
+
 class SVNIncorrectDatatype(SVNUnexpectedOutput):
   """Exception raised if invalid input is passed to the
   run_and_verify_* API"""
@@ -324,3 +329,16 @@
       raisable = main.SVNLineUnequal
 
     compare_and_display_lines(message, label, expected, actual, raisable)
+
+def verify_exit_code(message, actual, expected,
+                     raisable=SVNUnexpectedExitCode):
+  """Compare and display expected vs. actual exit codes:
+  if they don't match, print the difference (preceded by MESSAGE iff 
+  not None) and raise an exception."""
+
+  # main.spawn_process() (by virtue of main.wait_on_pipe()) will return an
+  # exit code of None on platforms not supporting Popen3
+  if actual is not None and expected != actual:
+    display_lines(message, "Exit Code",
+                  str(expected) + '\n', str(actual) + '\n')
+    raise raisable
Index: subversion/tests/cmdline/authz_tests.py
===================================================================
--- subversion/tests/cmdline/authz_tests.py	(revision 29740)
+++ subversion/tests/cmdline/authz_tests.py	(working copy)
@@ -117,10 +117,10 @@
 
   write_restrictive_svnserve_conf(sbox.repo_dir)
 
-  out, err = svntest.main.run_svn(1,
-                                  "delete",
-                                  sbox.repo_url + "/A",
-                                  "-m", "a log message");
+  exit_code, out, err = svntest.main.run_svn(1,
+                                             "delete",
+                                             sbox.repo_url + "/A",
+                                             "-m", "a log message");
   if out:
     raise svntest.verify.SVNUnexpectedStdout(out)
   if not err:
Index: subversion/tests/cmdline/autoprop_tests.py
===================================================================
--- subversion/tests/cmdline/autoprop_tests.py	(revision 29740)
+++ subversion/tests/cmdline/autoprop_tests.py	(working copy)
@@ -33,8 +33,8 @@
 def check_proplist(path, exp_out, config_dir):
   """Verify that property list on PATH has a value of EXP_OUT"""
 
-  out, err = svntest.main.run_svn(None, 'proplist', '--verbose', path,
-                                  '--config-dir', config_dir)
+  exit_code, out, err = svntest.main.run_svn(None, 'proplist', '--verbose',
+                                             path, '--config-dir', config_dir)
 
   out2 = []
   for line in out[1:]:
Index: subversion/tests/cmdline/basic_tests.py
===================================================================
--- subversion/tests/cmdline/basic_tests.py	(revision 29740)
+++ subversion/tests/cmdline/basic_tests.py	(working copy)
@@ -189,19 +189,19 @@
   # Unversioned paths, those that are not immediate children of a versioned
   # path, are skipped and do not raise an error
   xx_path = os.path.join(wc_dir, 'xx', 'xx')
-  out, err = svntest.actions.run_and_verify_svn("update xx/xx",
-                                                ["Skipped '"+xx_path+"'\n"], [],
-                                                'update', xx_path)
-  out, err = svntest.actions.run_and_verify_svn("update xx/xx",
-                                                [], [],
-                                                'update', '--quiet', xx_path)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(
+    "update xx/xx", ["Skipped '"+xx_path+"'\n"], [],
+    'update', xx_path)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(
+    "update xx/xx", [], [],
+    'update', '--quiet', xx_path)
 
   # URL's are also skipped.
   urls = ('http://localhost/a/b/c', 'http://localhost', 'svn://localhost')
   for url in urls:
-    out, err = svntest.actions.run_and_verify_svn("update " + url,
-                                                  ["Skipped '"+url+"'\n"], [],
-                                                  'update', url)
+    exit_code, out, err = svntest.actions.run_and_verify_svn(
+      "update " + url, ["Skipped '"+url+"'\n"], [],
+      'update', url)
 
 #----------------------------------------------------------------------
 def basic_mkdir_url(sbox):
@@ -1230,7 +1230,7 @@
 
   # import new files into repository
   url = sbox.repo_url + "/dirA/dirB/new_file"
-  output, errput =   svntest.actions.run_and_verify_svn(
+  exit_code, output, errput = svntest.actions.run_and_verify_svn(
     'Cannot change node kind', None, [], 'import',
     '-m', 'Log message for new import', new_path, url)
 
@@ -1365,7 +1365,7 @@
   # if someone runs this test on a system with "/nonexistent_path" in
   # the root directory, the test could fail, and that's just too bad :-).
 
-  output, errput = svntest.actions.run_and_verify_svn(
+  exit_code, output, errput = svntest.actions.run_and_verify_svn(
     None, None, svntest.verify.AnyOutput,
     'log', 'file:///nonexistent_path')
 
@@ -1432,7 +1432,7 @@
   open(foo_c_path, 'w')
   open(foo_o_path, 'w')
 
-  output, err = svntest.actions.run_and_verify_svn(
+  exit_code, output, err = svntest.actions.run_and_verify_svn(
     "No output where some expected", svntest.verify.AnyOutput, [],
     'add', dir_path)
 
@@ -1484,7 +1484,7 @@
   open(foo_lo_path, 'w')
   open(foo_rej_path, 'w')
 
-  output, err = svntest.actions.run_and_verify_svn(
+  exit_code, output, err = svntest.actions.run_and_verify_svn(
     "No output where some expected", svntest.verify.AnyOutput, [],
     'add', '--no-ignore', dir_path)
 
@@ -1573,7 +1573,7 @@
 
   iota_url = sbox.repo_url + '/iota'
 
-  output, errput = svntest.main.run_svn(1, 'co', iota_url)
+  exit_code, output, errput = svntest.main.run_svn(1, 'co', iota_url)
 
   for line in errput:
     if line.find("refers to a file") != -1:
@@ -1601,11 +1601,11 @@
   os.chdir(sbox.wc_dir)
 
   # Check that "info" works with 0, 1 and more than 1 explicit targets.
-  output, errput = svntest.main.run_svn(None, 'info')
+  exit_code, output, errput = svntest.main.run_svn(None, 'info')
   check_paths(output, ['.'])
-  output, errput = svntest.main.run_svn(None, 'info', 'iota')
+  exit_code, output, errput = svntest.main.run_svn(None, 'info', 'iota')
   check_paths(output, ['iota'])
-  output, errput = svntest.main.run_svn(None, 'info', 'iota', '.')
+  exit_code, output, errput = svntest.main.run_svn(None, 'info', 'iota', '.')
   check_paths(output, ['iota', '.'])
 
 def repos_root(sbox):
@@ -1621,17 +1621,19 @@
 
   sbox.build(read_only = True)
 
-  output, errput = svntest.main.run_svn(None, "info",
-                                        sbox.wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, "info",
+                                                   sbox.wc_dir)
   check_repos_root(output)
 
-  output, errput = svntest.main.run_svn(None, "info",
-                                        os.path.join(sbox.wc_dir, "A"))
+  exit_code, output, errput = svntest.main.run_svn(None, "info",
+                                                   os.path.join(sbox.wc_dir,
+                                                                "A"))
   check_repos_root(output)
 
-  output, errput = svntest.main.run_svn(None, "info",
-                                        os.path.join(sbox.wc_dir, "A", "B",
-                                                     "lambda"))
+  exit_code, output, errput = svntest.main.run_svn(None, "info",
+                                                   os.path.join(sbox.wc_dir,
+                                                                "A", "B",
+                                                                "lambda"))
   check_repos_root(output)
 
 def basic_peg_revision(sbox):
@@ -1651,16 +1653,16 @@
                        'ci', '-m', 'secret log msg', wc_file)
 
   # Without the trailing "@", expect failure.
-  output, errlines = svntest.actions.run_and_verify_svn(\
+  exit_code, output, errlines = svntest.actions.run_and_verify_svn(
     None, None, ".*Syntax error parsing revision 'abc'", 'cat', wc_file)
-  output, errlines = svntest.actions.run_and_verify_svn(\
+  exit_code, output, errlines = svntest.actions.run_and_verify_svn(
     None, None, ".*Syntax error parsing revision 'abc'", 'cat', url)
 
   # With the trailing "@", expect success.
-  output, errlines = svntest.actions.run_and_verify_svn(None, ["xyz\n"], [],
-                                                        'cat', wc_file+'@')
-  output, errlines = svntest.actions.run_and_verify_svn(None, ["xyz\n"], [],
-                                                        'cat', url+'@')
+  exit_code, output, errlines = svntest.actions.run_and_verify_svn(
+    None, ["xyz\n"], [], 'cat', wc_file+'@')
+  exit_code, output, errlines = svntest.actions.run_and_verify_svn(
+    None, ["xyz\n"], [], 'cat', url+'@')
 
 
 def info_nonhead(sbox):
@@ -1686,9 +1688,10 @@
                                         None,
                                         wc_dir)
   # Get info for old iota at r1.
-  output, errput = svntest.actions.run_and_verify_svn(None, None, [],
-                                                      'info',
-                                                      furl + '@1', '-r1')
+  exit_code, output, errput = svntest.actions.run_and_verify_svn(None, None,
+                                                                 [], 'info',
+                                                                 furl + '@1',
+                                                                 '-r1')
   got_url = 0
   for line in output:
     if line.find("URL:") >= 0:
@@ -2147,7 +2150,7 @@
 
   sbox.build(create_wc = False, read_only = True)
   idonotexist_url = sbox.repo_url + '/IdoNotExist'
-  output, errput = svntest.main.run_svn(1, 'info', idonotexist_url)
+  exit_code, output, errput = svntest.main.run_svn(1, 'info', idonotexist_url)
 
   # Check for the correct error message
   for line in errput:
Index: subversion/tests/cmdline/blame_tests.py
===================================================================
--- subversion/tests/cmdline/blame_tests.py	(revision 29740)
+++ subversion/tests/cmdline/blame_tests.py	(working copy)
@@ -123,12 +123,12 @@
   svntest.main.run_svn(None, 'ci',
                        '-m', '', iota)
 
-  output, errput = svntest.main.run_svn(2, 'blame', iota)
+  exit_code, output, errput = svntest.main.run_svn(2, 'blame', iota)
   if (len(errput) != 1) or (errput[0].find('Skipping') == -1):
     raise svntest.Failure
 
   # But with --force, it should work.
-  output, errput = svntest.main.run_svn(2, 'blame', '--force', iota)
+  exit_code, output, errput = svntest.main.run_svn(2, 'blame', '--force', iota)
   if (len(errput) != 0 or len(output) != 4):
     raise svntest.Failure
 
@@ -155,7 +155,7 @@
   # probably include a leading slash on the path, but we'll tolerate
   # it either way, since either way it would still be a clean error.
   expected_error  = ".*'[/]{0,1}A' is not a file"
-  outlines, errlines = svntest.main.run_svn(1, 'blame', dir)
+  exit_code, outlines, errlines = svntest.main.run_svn(1, 'blame', dir)
 
   # Verify expected error message is output
   for line in errlines:
@@ -185,9 +185,10 @@
                                         None, None, wc_dir)
 
   # Retrieve last changed date from svn info
-  output, error = svntest.actions.run_and_verify_svn(None, None, [],
-                                                     'log', file_path,
-                                                     '--xml', '-r1:2')
+  exit_code, output, error = svntest.actions.run_and_verify_svn(
+    None, None, [],
+    'log', file_path, '--xml', '-r1:2')
+
   date1 = None
   date2 = None
   for line in output:
@@ -224,9 +225,10 @@
               '</target>\n',
               '</blame>\n']
 
-  output, error = svntest.actions.run_and_verify_svn(None, None, [],
-                                                     'blame', file_path,
-                                                     '--xml')
+  exit_code, output, error = svntest.actions.run_and_verify_svn(
+    None, None, [],
+    'blame', file_path, '--xml')
+
   for i in range(0, len(output)):
     if output[i] != template[i]:
       raise svntest.Failure
@@ -253,17 +255,16 @@
     svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                           None, None, wc_dir)
 
-  output, error = svntest.actions.run_and_verify_svn(None, None, [],
-                                                     'blame', file_path,
-                                                     '-rHEAD:HEAD')
+  exit_code, output, error = svntest.actions.run_and_verify_svn(
+    None, None, [],
+    'blame', file_path, '-rHEAD:HEAD')
 
   if output[0].find(" - This is the file 'iota'.") == -1:
     raise svntest.Failure
 
-  output, error = svntest.actions.run_and_verify_svn(None, None, [],
-                                                     'blame', file_path,
-                                                     '--verbose',
-                                                     '-rHEAD:HEAD')
+  exit_code, output, error = svntest.actions.run_and_verify_svn(
+    None, None, [],
+    'blame', file_path, '--verbose', '-rHEAD:HEAD')
 
   if output[0].find(" - This is the file 'iota'.") == -1:
     raise svntest.Failure
@@ -330,9 +331,9 @@
     svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                           None, None, wc_dir)
 
-    output, error = svntest.actions.run_and_verify_svn(None, None, [],
-                                                       'blame', file_path,
-                                                       '-r1:HEAD')
+    exit_code, output, error = svntest.actions.run_and_verify_svn(
+      None, None, [],
+      'blame', file_path, '-r1:HEAD')
 
     # output is a list of lines, there should be 3 lines
     if len(output) != 3:
@@ -378,8 +379,9 @@
     "     2    jrandom     C    c    \n",
     ]
 
-  output, error = svntest.actions.run_and_verify_svn(None, expected_output, [],
-                                     'blame', '-x', '-w', file_path)
+  exit_code, output, error = svntest.actions.run_and_verify_svn(
+    None, expected_output, [],
+    'blame', '-x', '-w', file_path)
 
   # commit some changes
   svntest.main.file_write(file_path,
@@ -439,8 +441,9 @@
     "     3    jrandom Cc\n",
     ]
 
-  output, error = svntest.actions.run_and_verify_svn(None, expected_output, [],
-                                     'blame', '-x', '--ignore-eol-style', file_path)
+  exit_code, output, error = svntest.actions.run_and_verify_svn(
+    None, expected_output, [],
+    'blame', '-x', '--ignore-eol-style', file_path)
 
 
 def blame_merge_info(sbox):
@@ -452,8 +455,10 @@
   wc_dir = sbox.wc_dir
   iota_path = os.path.join(wc_dir, 'trunk', 'iota')
 
-  output, error = svntest.actions.run_and_verify_svn(None, None, [],
-                                                     'blame', '-g', iota_path)
+  exit_code, output, error = svntest.actions.run_and_verify_svn(
+    None, None, [],
+    'blame', '-g', iota_path)
+
   expected_blame = [
       { 'revision' : 2,
         'author' : 'jrandom',
@@ -478,9 +483,10 @@
   wc_dir = sbox.wc_dir
   upsilon_path = os.path.join(wc_dir, 'trunk', 'A', 'upsilon')
 
-  output, error = svntest.actions.run_and_verify_svn(None, None, [],
-                                                     'blame', '-g',
-                                                     upsilon_path)
+  exit_code, output, error = svntest.actions.run_and_verify_svn(
+    None, None, [],
+    'blame', '-g', upsilon_path)
+
   expected_blame = [
       { 'revision' : 4,
         'author' : 'jrandom',
Index: subversion/tests/cmdline/cat_tests.py
===================================================================
--- subversion/tests/cmdline/cat_tests.py	(revision 29740)
+++ subversion/tests/cmdline/cat_tests.py	(working copy)
@@ -43,20 +43,19 @@
 
   A_path = os.path.join(sbox.wc_dir, 'A')
 
-  svntest.actions.run_and_verify_svn('No error where one is expected',
-                                     None, svntest.verify.AnyOutput,
-                                     'cat', A_path)
+  svntest.actions.run_and_verify_svn2('No error where one is expected',
+                                      None, svntest.verify.AnyOutput,
+                                      0, 'cat', A_path)
 
 def cat_remote_directory(sbox):
   "cat a remote directory"
   sbox.build(create_wc = False, read_only = True)
 
   A_url = sbox.repo_url + '/A'
+  svntest.actions.run_and_verify_svn2('No error where one is expected',
+                                      None, svntest.verify.AnyOutput,
+                                      0, 'cat', A_url)
 
-  svntest.actions.run_and_verify_svn('No error where one is expected',
-                                     None, svntest.verify.AnyOutput,
-                                     'cat', A_url)
-
 def cat_base(sbox):
   "cat a file at revision BASE"
   sbox.build(read_only = True)
@@ -66,7 +65,7 @@
   mu_path = os.path.join(wc_dir, 'A', 'mu')
   svntest.main.file_append(mu_path, 'Appended text')
 
-  outlines, errlines = svntest.main.run_svn(0, 'cat', mu_path)
+  exit_code, outlines, errlines = svntest.main.run_svn(0, 'cat', mu_path)
 
   # Verify the expected output
   expected_output = svntest.main.greek_state.desc['A/mu'].contents
@@ -81,11 +80,10 @@
   wc_dir = sbox.wc_dir
 
   bogus_path = os.path.join(wc_dir, 'A', 'bogus')
+  svntest.actions.run_and_verify_svn2('No error where one is expected',
+                                      None, svntest.verify.AnyOutput,
+                                      0, 'cat', bogus_path)
 
-  svntest.actions.run_and_verify_svn('No error where one is expected',
-                                     None, svntest.verify.AnyOutput,
-                                     'cat', bogus_path)
-
 def cat_skip_uncattable(sbox):
   "cat should skip uncattable resources"
   sbox.build(read_only = True)
@@ -109,13 +107,13 @@
     if item_to_cat == new_file_path:
       expected_err = ["svn: warning: '" + item_to_cat + "'" + \
                      " is not under version control\n"]
-      svntest.actions.run_and_verify_svn(None, None, expected_err,
-                                         'cat', item_to_cat)
+      svntest.actions.run_and_verify_svn2(None, None, expected_err, 0,
+                                          'cat', item_to_cat)
     elif os.path.isdir(item_to_cat):
       expected_err = ["svn: warning: '" + item_to_cat + "'" + \
                      " refers to a directory\n"]
-      svntest.actions.run_and_verify_svn(None, None,
-                                         expected_err, 'cat', item_to_cat)
+      svntest.actions.run_and_verify_svn2(None, None, expected_err, 0,
+                                          'cat', item_to_cat)
     else:
       svntest.actions.run_and_verify_svn(None,
                                          ["This is the file '"+file+"'.\n"],
@@ -127,17 +125,17 @@
   expected_out = ["This is the file 'rho'.\n"]
   expected_err1 = ["svn: warning: '" + G_path + "'"
                    + " refers to a directory\n"]
-  svntest.actions.run_and_verify_svn(None, expected_out, expected_err1,
-                                     'cat', rho_path, G_path)
+  svntest.actions.run_and_verify_svn2(None, expected_out, expected_err1, 0,
+                                      'cat', rho_path, G_path)
 
   expected_err2 = ["svn: warning: '" + new_file_path + "'"
                    + " is not under version control\n"]
-  svntest.actions.run_and_verify_svn(None, expected_out, expected_err2,
-                                     'cat', rho_path, new_file_path)
+  svntest.actions.run_and_verify_svn2(None, expected_out, expected_err2, 0,
+                                      'cat', rho_path, new_file_path)
 
-  svntest.actions.run_and_verify_svn(None, expected_out,
-                                     expected_err1 + expected_err2,
-                                     'cat', rho_path, G_path, new_file_path)
+  svntest.actions.run_and_verify_svn2(None, expected_out,
+                                      expected_err1 + expected_err2, 0,
+                                      'cat', rho_path, G_path, new_file_path)
 
 
 ########################################################################
Index: subversion/tests/cmdline/changelist_tests.py
===================================================================
--- subversion/tests/cmdline/changelist_tests.py	(revision 29740)
+++ subversion/tests/cmdline/changelist_tests.py	(working copy)
@@ -228,23 +228,23 @@
   ### First, we play with just adding to changelists ###
   
   # svn changelist foo WC_DIR
-  output, errput = svntest.main.run_svn(None, "changelist", "foo",
-                                        wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, "changelist", "foo",
+                                                   wc_dir)
   verify_changelist_output(output) # nothing expected
 
   # svn changelist foo WC_DIR --depth files
-  output, errput = svntest.main.run_svn(None, "changelist", "foo",
-                                        "--depth", "files",
-                                        wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, "changelist", "foo",
+                                                   "--depth", "files",
+                                                   wc_dir)
   expected_adds = {
     os.path.join(wc_dir, 'iota') : 'foo',
     }
   verify_changelist_output(output, expected_adds)
   
   # svn changelist foo WC_DIR --depth infinity
-  output, errput = svntest.main.run_svn(None, "changelist", "foo",
-                                        "--depth", "infinity",
-                                        wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, "changelist", "foo",
+                                                   "--depth", "infinity",
+                                                   wc_dir)
   expected_adds = {
     os.path.join(wc_dir, 'A', 'B', 'E', 'alpha') : 'foo',
     os.path.join(wc_dir, 'A', 'B', 'E', 'beta') : 'foo',
@@ -263,9 +263,10 @@
   ### Now, change some changelists ###
   
   # svn changelist bar WC_DIR/A/D --depth infinity
-  output, errput = svntest.main.run_svn(".*", "changelist", "bar",
-                                        "--depth", "infinity",
-                                        os.path.join(wc_dir, 'A', 'D'))
+  exit_code, output, errput = svntest.main.run_svn(".*", "changelist", "bar",
+                                                   "--depth", "infinity",
+                                                   os.path.join(wc_dir,
+                                                                'A', 'D'))
   expected_adds = {
     os.path.join(wc_dir, 'A', 'D', 'G', 'pi') : 'bar',
     os.path.join(wc_dir, 'A', 'D', 'G', 'rho') : 'bar',
@@ -278,9 +279,10 @@
   verify_changelist_output(output, expected_adds)
 
   # svn changelist baz WC_DIR/A/D/H --depth infinity
-  output, errput = svntest.main.run_svn(".*", "changelist", "baz",
-                                        "--depth", "infinity",
-                                        os.path.join(wc_dir, 'A', 'D', 'H'))
+  exit_code, output, errput = svntest.main.run_svn(".*", "changelist", "baz",
+                                                   "--depth", "infinity",
+                                                   os.path.join(wc_dir, 'A', 
+                                                                'D', 'H'))
   expected_adds = {
     os.path.join(wc_dir, 'A', 'D', 'H', 'chi') : 'baz',
     os.path.join(wc_dir, 'A', 'D', 'H', 'omega') : 'baz',
@@ -291,10 +293,11 @@
   ### Now, let's selectively rename some changelists ###
 
   # svn changelist foo-rename WC_DIR --depth infinity --changelist foo
-  output, errput = svntest.main.run_svn(".*", "changelist", "foo-rename",
-                                        "--depth", "infinity",
-                                        "--changelist", "foo",
-                                        wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(".*", "changelist",
+                                                   "foo-rename",
+                                                   "--depth", "infinity",
+                                                   "--changelist", "foo",
+                                                   wc_dir)
   expected_adds = {
     os.path.join(wc_dir, 'A', 'B', 'E', 'alpha') : 'foo-rename',
     os.path.join(wc_dir, 'A', 'B', 'E', 'beta') : 'foo-rename',
@@ -306,11 +309,10 @@
 
   # svn changelist bar WC_DIR --depth infinity
   #     --changelist foo-rename --changelist baz
-  output, errput = svntest.main.run_svn(".*", "changelist", "bar",
-                                        "--depth", "infinity",
-                                        "--changelist", "foo-rename",
-                                        "--changelist", "baz",
-                                        wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(
+    ".*", "changelist", "bar", "--depth", "infinity",
+    "--changelist", "foo-rename", "--changelist", "baz", wc_dir)
+
   expected_adds = {
     os.path.join(wc_dir, 'A', 'B', 'E', 'alpha') : 'bar',
     os.path.join(wc_dir, 'A', 'B', 'E', 'beta') : 'bar',
@@ -326,23 +328,25 @@
   ### Okay.  Time to remove some stuff from changelists now. ###
   
   # svn changelist --remove WC_DIR
-  output, errput = svntest.main.run_svn(None, "changelist", "--remove",
-                                        wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, "changelist",
+                                                   "--remove", wc_dir)
   verify_changelist_output(output) # nothing expected
 
   # svn changelist --remove WC_DIR --depth files
-  output, errput = svntest.main.run_svn(None, "changelist", "--remove",
-                                        "--depth", "files",
-                                        wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, "changelist",
+                                                   "--remove",
+                                                   "--depth", "files",
+                                                   wc_dir)
   expected_removals = {
     os.path.join(wc_dir, 'iota') : None,
     }
   verify_changelist_output(output, None, expected_removals)
   
   # svn changelist --remove WC_DIR --depth infinity
-  output, errput = svntest.main.run_svn(None, "changelist", "--remove",
-                                        "--depth", "infinity",
-                                        wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, "changelist",
+                                                   "--remove",
+                                                   "--depth", "infinity",
+                                                   wc_dir)
   expected_removals = {
     os.path.join(wc_dir, 'A', 'B', 'E', 'alpha') : None,
     os.path.join(wc_dir, 'A', 'B', 'E', 'beta') : None,
@@ -365,10 +369,11 @@
   ### Now, do selective changelist removal ###
   
   # svn changelist --remove WC_DIR --depth infinity --changelist a
-  output, errput = svntest.main.run_svn(None, "changelist", "--remove",
-                                        "--depth", "infinity",
-                                        "--changelist", "a",
-                                        wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, "changelist",
+                                                   "--remove",
+                                                   "--depth", "infinity",
+                                                   "--changelist", "a",
+                                                   wc_dir)
   expected_removals = {
     os.path.join(wc_dir, 'A', 'B', 'E', 'alpha') : None,
     os.path.join(wc_dir, 'A', 'B', 'E', 'beta') : None,
@@ -381,11 +386,12 @@
 
   # svn changelist --remove WC_DIR --depth infinity
   #     --changelist i --changelist o
-  output, errput = svntest.main.run_svn(None, "changelist", "--remove",
-                                        "--depth", "infinity",
-                                        "--changelist", "i",
-                                        "--changelist", "o",
-                                        wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, "changelist",
+                                                   "--remove",
+                                                   "--depth", "infinity",
+                                                   "--changelist", "i",
+                                                   "--changelist", "o",
+                                                   wc_dir)
   expected_removals = {
     os.path.join(wc_dir, 'A', 'D', 'G', 'pi') : None,
     os.path.join(wc_dir, 'A', 'D', 'G', 'rho') : None,
@@ -517,7 +523,7 @@
         args.append(depth)
 
       # Run 'svn info ...'
-      output, errput = svntest.main.run_svn(None, *args)
+      exit_code, output, errput = svntest.main.run_svn(None, *args)
 
       # Filter the output for lines that begin with 'Path:', and
       # reduce even those lines to just the actual path.
@@ -588,7 +594,7 @@
           args.append(wc_dir)
   
         # Run 'svn diff ...'
-        output, errput = svntest.main.run_svn(None, *args)
+        exit_code, output, errput = svntest.main.run_svn(None, *args)
   
         # Filter the output for lines that begin with 'Index:', and
         # reduce even those lines to just the actual path.
@@ -670,21 +676,22 @@
                              expected_disk.old_tree())
 
   # Propget 'name' in files in changelists 'a' and 'i' to depth files.
-  output, errput = svntest.main.run_svn(None, "pget",
-                                        "--depth", "files", "name",
-                                        "--changelist", "a",
-                                        "--changelist", "i",
-                                        wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, "pget",
+                                                   "--depth", "files", "name",
+                                                   "--changelist", "a",
+                                                   "--changelist", "i",
+                                                   wc_dir)
   verify_pget_output(output, {
     os.path.join(wc_dir, 'iota') : 'value',
     })
   
   # Propget 'name' in files in changelists 'a' and 'i' to depth infinity.
-  output, errput = svntest.main.run_svn(None, "pget",
-                                        "--depth", "infinity", "name",
-                                        "--changelist", "a",
-                                        "--changelist", "i",
-                                        wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, "pget",
+                                                   "--depth", "infinity",
+                                                   "name",
+                                                   "--changelist", "a",
+                                                   "--changelist", "i",
+                                                   wc_dir)
   verify_pget_output(output, {
     os.path.join(wc_dir, 'A', 'D', 'gamma')      : 'value',
     os.path.join(wc_dir, 'A', 'B', 'E', 'alpha') : 'value',
Index: subversion/tests/cmdline/checkout_tests.py
===================================================================
--- subversion/tests/cmdline/checkout_tests.py	(revision 29740)
+++ subversion/tests/cmdline/checkout_tests.py	(working copy)
@@ -161,11 +161,9 @@
 
   # Checkout the standard greek repos into a directory that has a dir named
   # "iota" obstructing the file "iota" in the repos.  This should fail.
-  sout, serr = svntest.actions.run_and_verify_svn("Expected error during co",
-                                                  None,
-                                                  svntest.verify.AnyOutput,
-                                                  "co", "--force",
-                                                  sbox.repo_url, other_wc)
+  exit_code, sout, serr = svntest.actions.run_and_verify_svn(
+    "Expected error during co", None, svntest.verify.AnyOutput,
+    "co", "--force", sbox.repo_url, other_wc)
 
   test_stderr(".*Failed to add file.*a non-file object of the same name " \
               "already exists", serr)
@@ -184,11 +182,9 @@
 
   # Checkout the standard greek repos into a directory that has a file named
   # "A" obstructing the dir "A" in the repos.  This should fail.
-  sout, serr = svntest.actions.run_and_verify_svn("Expected error during co",
-                                                  None,
-                                                  svntest.verify.AnyOutput,
-                                                  "co", "--force",
-                                                  sbox.repo_url, other_wc)
+  exit_code, sout, serr = svntest.actions.run_and_verify_svn(
+    "Expected error during co", None, svntest.verify.AnyOutput,
+    "co", "--force", sbox.repo_url, other_wc)
 
   test_stderr(".*Failed to add directory.*a non-directory object of the " \
               "same name already exists", serr)
@@ -280,11 +276,9 @@
 
   # Checkout the first repos into "other/A".  This should fail since the
   # obstructing versioned directory points to a different URL.
-  sout, serr = svntest.actions.run_and_verify_svn("Expected error during co",
-                                                  None,
-                                                  svntest.verify.AnyOutput,
-                                                  "co", "--force",
-                                                  sbox.repo_url, other_wc_dir)
+  exit_code, sout, serr = svntest.actions.run_and_verify_svn(
+    "Expected error during co", None, svntest.verify.AnyOutput,
+    "co", "--force", sbox.repo_url, other_wc_dir)
 
   test_stderr("svn: Failed to add directory '.*A': a versioned directory " \
               "of the same name already exists", serr)
@@ -676,41 +670,33 @@
                                      omicron_path)
 
   # Try to co M's Parent.
-  sout, serr = svntest.actions.run_and_verify_svn("Checkout XPASS",
-                                                  [], svntest.verify.AnyOutput,
-                                                  'checkout',
-                                                  sbox.repo_url + '/A/D',
-                                                  D_path)
+  exit_code, sout, serr = svntest.actions.run_and_verify_svn(
+    "Checkout XPASS", [], svntest.verify.AnyOutput,
+    'checkout', sbox.repo_url + '/A/D', D_path)
 
   test_stderr("svn: Failed to add directory '.*M': a versioned " \
               "directory of the same name already exists\n", serr)
 
   # --force shouldn't help either.
-  sout, serr = svntest.actions.run_and_verify_svn("Checkout XPASS",
-                                                  [], svntest.verify.AnyOutput,
-                                                  'checkout',
-                                                  sbox.repo_url + '/A/D',
-                                                  D_path, '--force')
+  exit_code, sout, serr = svntest.actions.run_and_verify_svn(
+    "Checkout XPASS", [], svntest.verify.AnyOutput,
+    'checkout', sbox.repo_url + '/A/D', D_path, '--force')
 
   test_stderr("svn: Failed to add directory '.*M': a versioned " \
               "directory of the same name already exists\n", serr)
 
   # Try to co omicron's parent.
-  sout, serr = svntest.actions.run_and_verify_svn("Checkout XPASS",
-                                                  [], svntest.verify.AnyOutput,
-                                                  'checkout',
-                                                  sbox.repo_url + '/A/B/F',
-                                                  F_path)
+  exit_code, sout, serr = svntest.actions.run_and_verify_svn(
+    "Checkout XPASS", [], svntest.verify.AnyOutput,
+    'checkout', sbox.repo_url + '/A/B/F', F_path)
 
   test_stderr("svn: Failed to add file '.*omicron': a file of the same " \
               "name is already scheduled for addition with history\n", serr)
 
   # Again, --force shouldn't matter.
-  sout, serr = svntest.actions.run_and_verify_svn("Checkout XPASS",
-                                                  [], svntest.verify.AnyOutput,
-                                                  'checkout',
-                                                  sbox.repo_url + '/A/B/F',
-                                                  F_path, '--force')
+  exit_code, sout, serr = svntest.actions.run_and_verify_svn(
+    "Checkout XPASS", [], svntest.verify.AnyOutput,
+    'checkout', sbox.repo_url + '/A/B/F', F_path, '--force')
 
   test_stderr("svn: Failed to add file '.*omicron': a file of the same " \
               "name is already scheduled for addition with history\n", serr)
Index: subversion/tests/cmdline/commit_tests.py
===================================================================
--- subversion/tests/cmdline/commit_tests.py	(revision 29740)
+++ subversion/tests/cmdline/commit_tests.py	(working copy)
@@ -1338,7 +1338,8 @@
                                      'commit', '-m', 'log', other_wc_dir)
 
   # Now list the txns in the repo. The list should be empty.
-  output, errput = svntest.main.run_svnadmin('lstxns', sbox.repo_dir)
+  exit_code, output, errput = svntest.main.run_svnadmin('lstxns',
+                                                        sbox.repo_dir)
   svntest.verify.compare_and_display_lines(
     "Error running 'svnadmin lstxns'.",
     'STDERR', [], errput)
@@ -1647,8 +1648,8 @@
 
   # Attempt to delete omega.  This should return an (expected)
   # out-of-dateness error.
-  outlines, errlines = svntest.main.run_svn(1, 'commit', '-m', 'blah',
-                                            omega_path)
+  exit_code, outlines, errlines = svntest.main.run_svn(1, 'commit', '-m',
+                                                       'blah', omega_path)
   for line in errlines:
     if re.match(".*[Oo]ut.of.date.*", line):
       break
@@ -1657,7 +1658,8 @@
 
   # Attempt to delete directory C.  This should return an (expected)
   # out-of-dateness error.
-  outlines, errlines = svntest.main.run_svn(1, 'commit', '-m', 'blah', C_path)
+  exit_code, outlines, errlines = svntest.main.run_svn(1, 'commit', '-m',
+                                                       'blah', C_path)
   for line in errlines:
     if re.match(".*[Oo]ut.of.date.*", line):
       break
@@ -1716,7 +1718,7 @@
                                      svntest.verify.AnyOutput, [],
                                      'pset', 'fish', 'food', wc_dir)
   os.chdir(wc_dir)
-  out, err = svntest.actions.run_and_verify_svn(
+  exit_code, out, err = svntest.actions.run_and_verify_svn(
     "Commit succeeded when should have failed.",
     None, svntest.verify.AnyOutput,
     'ci', '--editor-cmd', 'no_such-editor')
@@ -1784,29 +1786,29 @@
       raise svntest.Failure("Failed to find match_re in " + str(errlines))
 
   # add file to wc
-  outlines, errlines = svntest.main.run_svn(1, 'add', tab_file)
+  exit_code, outlines, errlines = svntest.main.run_svn(1, 'add', tab_file)
   match_bad_tab_path(tab_file, errlines)
 
   # add dir to wc
-  outlines, errlines = svntest.main.run_svn(1, 'add', tab_dir)
+  exit_code, outlines, errlines = svntest.main.run_svn(1, 'add', tab_dir)
   match_bad_tab_path(tab_dir, errlines)
 
   # mkdir URL
-  outlines, errlines = svntest.main.run_svn(1,
-                                            'mkdir', '-m', 'msg', tab_url)
+  exit_code, outlines, errlines = svntest.main.run_svn(1, 'mkdir',
+                                                       '-m', 'msg', tab_url)
   match_bad_tab_path(tab_dir, errlines)
 
   # copy URL
   svntest.main.run_svn(1,
                        'mkdir', '-m', 'msg', source_url)
-  outlines, errlines = svntest.main.run_svn(1,
-                                            'copy', '-m', 'msg',
-                                            source_url, tab_url)
+  exit_code, outlines, errlines = svntest.main.run_svn(1, 'copy',
+                                                       '-m', 'msg',
+                                                       source_url, tab_url)
   match_bad_tab_path(tab_dir, errlines)
 
   # mv URL
-  outlines, errlines = svntest.main.run_svn(1, 'mv', '-m', 'msg',
-                                            source_url, tab_url)
+  exit_code, outlines, errlines = svntest.main.run_svn(1, 'mv', '-m', 'msg',
+                                                       source_url, tab_url)
   match_bad_tab_path(tab_dir, errlines)
 
 #----------------------------------------------------------------------
@@ -2272,9 +2274,8 @@
   svntest.main.file_append(iota_path, "More stuff in iota")
 
   # Commit, expect error code 1
-  actual_stdout, actual_stderr = svntest.main.run_svn(1,
-                                                      'ci', '--quiet',
-                                                      '-m', 'log msg', wc_dir)
+  exit_code, actual_stdout, actual_stderr = svntest.main.run_svn(
+    1, 'ci', '--quiet', '-m', 'log msg', wc_dir)
 
   # No stdout expected
   svntest.verify.compare_and_display_lines('Start-commit hook test',
@@ -2316,9 +2317,8 @@
   svntest.main.file_append(iota_path, "More stuff in iota")
 
   # Commit, expect error code 1
-  actual_stdout, actual_stderr = svntest.main.run_svn(1,
-                                                      'ci', '--quiet',
-                                                      '-m', 'log msg', wc_dir)
+  exit_code, actual_stdout, actual_stderr = svntest.main.run_svn(
+    1, 'ci', '--quiet', '-m', 'log msg', wc_dir)
 
   # No stdout expected
   svntest.verify.compare_and_display_lines('Pre-commit hook test',
Index: subversion/tests/cmdline/copy_tests.py
===================================================================
--- subversion/tests/cmdline/copy_tests.py	(revision 29740)
+++ subversion/tests/cmdline/copy_tests.py	(working copy)
@@ -915,7 +915,7 @@
   svntest.actions.run_and_verify_status(wc_dir, expected_output)
 
   # Modification will only show up if timestamps differ
-  out,err = svntest.main.run_svn(None, 'diff', pi_path)
+  exit_code, out, err = svntest.main.run_svn(None, 'diff', pi_path)
   if err or not out:
     print "diff failed"
     raise svntest.Failure
@@ -1334,7 +1334,7 @@
     expected_disk.add({ dst: Item(contents=text) })
 
     # Check that the copied-from revision == from_rev.
-    output, errput = svntest.main.run_svn(None, "info", dst_path)
+    exit_code, output, errput = svntest.main.run_svn(None, "info", dst_path)
     for line in output:
       if line.rstrip() == "Copied From Rev: " + str(from_rev):
         break
@@ -1472,9 +1472,9 @@
   wc2_dir = sbox2.wc_dir
 
   # Attempt a copy between different repositories.
-  out, err = svntest.main.run_svn(1, 'cp',
-                                  os.path.join(wc2_dir, 'A'),
-                                  os.path.join(wc_dir, 'A', 'B'))
+  exit_code, out, err = svntest.main.run_svn(1, 'cp',
+                                             os.path.join(wc2_dir, 'A'),
+                                             os.path.join(wc_dir, 'A', 'B'))
   for line in err:
     if line.find("it is not from repository") != -1:
       break
@@ -1503,9 +1503,9 @@
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # Copy to schedule=delete fails
-  out, err = svntest.main.run_svn(1, 'cp',
-                                  os.path.join(B_path, 'E'),
-                                  os.path.join(B_path, 'F'))
+  exit_code, out, err = svntest.main.run_svn(1, 'cp',
+                                             os.path.join(B_path, 'E'),
+                                             os.path.join(B_path, 'F'))
   for line in err:
     if line.find("is scheduled for deletion") != -1:
       break
@@ -1542,14 +1542,15 @@
   # Attempts to revert the schedule=delete will fail, but should not
   # break the wc.  It's very important that the directory revert fails
   # since it's a placeholder rather than a full hierarchy
-  out, err = svntest.main.run_svn(1, 'revert', '--recursive',
-                                  os.path.join(B2_path, 'F'))
+  exit_code, out, err = svntest.main.run_svn(1, 'revert', '--recursive',
+                                             os.path.join(B2_path, 'F'))
   for line in err:
     if line.find("Error restoring text") != -1:
       break
   else:
     raise svntest.Failure
-  out, err = svntest.main.run_svn(1, 'revert', os.path.join(B2_path, 'lambda'))
+  exit_code, out, err = svntest.main.run_svn(1, 'revert',
+                                             os.path.join(B2_path, 'lambda'))
   for line in err:
     if line.find("Error restoring text") != -1:
       break
@@ -1603,9 +1604,8 @@
 
   # Expect failure on 'svn cp SRC DST' where one or more ancestor
   # directories of DST do not exist
-  out, err = svntest.main.run_svn(1,
-                                  'cp', dirURL1, dirURL2,
-                                  '-m', 'fooogle')
+  exit_code, out, err = svntest.main.run_svn(1, 'cp', dirURL1, dirURL2,
+                                             '-m', 'fooogle')
   for err_line in err:
     if re.match (msg, err_line):
       break
@@ -2384,10 +2384,9 @@
 
   # Move the moved dir: D_moved back to its starting
   # location at A/D.
-  out, err = svntest.actions.run_and_verify_svn(None, None,
-                                                svntest.verify.AnyOutput,
-                                                'mv', D_move_path,
-                                                D_path)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(
+    None, None, svntest.verify.AnyOutput,
+    'mv', D_move_path, D_path)
 
   for line in err:
     if re.match('.*Cannot copy to .*as it is scheduled for deletion',
@@ -3788,8 +3787,8 @@
                                        chi_url, other_psi_path);
     svntest.actions.run_and_verify_svn(None, None, [], 'up',
                                        other_wc_dir)
-    output, errput = svntest.main.run_svn(None, 'proplist',
-                                          '-v', other_omega_path)
+    exit_code, output, errput = svntest.main.run_svn(None, 'proplist',
+                                                     '-v', other_omega_path)
     if len(errput):
       raise svntest.Failure("unexpected error output: %s" % errput)
     if len(output):
Index: subversion/tests/cmdline/depth_tests.py
===================================================================
--- subversion/tests/cmdline/depth_tests.py	(revision 29740)
+++ subversion/tests/cmdline/depth_tests.py	(working copy)
@@ -89,7 +89,8 @@
   """Verifies that PATH has depth DEPTH.  MSG is the failure message."""
   if depth == "infinity":
     # Check for absence of depth line.
-    out, err = svntest.actions.run_and_verify_svn(None, None, [], "info", path)
+    exit_code, out, err = svntest.actions.run_and_verify_svn(None, None,
+                                                             [], "info", path)
     for line in out:
       if line.startswith("Depth:"):
         raise svntest.failure(msg)
@@ -1370,10 +1371,9 @@
     "empty" : sbox.clone_dependent(copy_wc=True),
     }
 
-  output, err = \
-    svntest.actions.run_and_verify_svn(None, None, [],
-                                       "delete", "-m", "Delete A.",
-                                       sbox.repo_url + "/A")
+  exit_code, output, err = svntest.actions.run_and_verify_svn(
+    None, None, [],
+    "delete", "-m", "Delete A.", sbox.repo_url + "/A")
 
   def empty_output(wc_dir):
     return svntest.wc.State(wc_dir, { })
Index: subversion/tests/cmdline/diff_tests.py
===================================================================
--- subversion/tests/cmdline/diff_tests.py	(revision 29740)
+++ subversion/tests/cmdline/diff_tests.py	(working copy)
@@ -125,15 +125,15 @@
   was_cwd = os.getcwd()
   os.chdir(wc_dir)
 
-  diff_output, err_output = svntest.main.run_svn(None, 'diff',
-                                                 repo_subset)
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            repo_subset)
   if check_fn(diff_output):
     return 1
 
   if do_diff_r:
-    diff_output, err_output = svntest.main.run_svn(None,
-                                                   'diff', '-r', 'HEAD',
-                                                   repo_subset)
+    exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                              '-r', 'HEAD',
+                                                              repo_subset)
     if check_fn(diff_output):
       return 1
 
@@ -306,13 +306,13 @@
   change_fn()
 
   # diff without revision doesn't use an editor
-  diff_output, err_output = svntest.main.run_svn(None, 'diff')
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff')
   if check_fn(diff_output):
     raise svntest.Failure
 
   # diff with revision runs an editor
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r', 'HEAD')
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            '-r', 'HEAD')
   if check_fn(diff_output):
     raise svntest.Failure
 
@@ -320,8 +320,8 @@
                        'ci', '-m', 'log msg')
   svntest.main.run_svn(None,
                        'up')
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r', revision)
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            '-r', revision)
   if check_fn(diff_output):
     raise svntest.Failure
 
@@ -336,8 +336,8 @@
   was_cwd = os.getcwd()
   os.chdir(wc_dir)
 
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r', rev_check)
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            '-r', rev_check)
   if check_fn(diff_output):
     raise svntest.Failure
   os.chdir(was_cwd)
@@ -367,9 +367,10 @@
   was_cwd = os.getcwd()
   os.chdir(wc_dir)
 
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r',
-                                                 `rev2` + ':' + `rev1`)
+  exit_code, diff_output, err_output = svntest.main.run_svn(None,
+                                                            'diff', '-r',
+                                                            `rev2` + ':'
+                                                                   + `rev1`)
   if check_fn(diff_output):
     raise svntest.Failure
 
@@ -477,21 +478,23 @@
   # recursively, there is only one change even though D is the anchor
 
   # full diff has three changes
-  diff_output, err_output = svntest.main.run_svn(None, 'diff', '-r', '1',
-                                                 os.path.join(wc_dir, 'A', 'D'))
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+    None, 'diff', '-r', '1', os.path.join(wc_dir, 'A', 'D'))
+
   if count_diff_output(diff_output) != 3:
     raise svntest.Failure
 
   # non-recursive has one change
-  diff_output, err_output = svntest.main.run_svn(None, 'diff', '-r', '1', '-N',
-                                                 os.path.join(wc_dir, 'A', 'D'))
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+    None, 'diff', '-r', '1', '-N', os.path.join(wc_dir, 'A', 'D'))
+
   if count_diff_output(diff_output) != 1:
     raise svntest.Failure
 
   # diffing a directory doesn't pick up other diffs in the anchor
-  diff_output, err_output = svntest.main.run_svn(None, 'diff', '-r', '1',
-                                                 os.path.join(wc_dir,
-                                                              'A', 'D', 'G'))
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+    None, 'diff', '-r', '1', os.path.join(wc_dir, 'A', 'D', 'G'))
+
   if count_diff_output(diff_output) != 1:
     raise svntest.Failure
 
@@ -531,9 +534,8 @@
 
   svntest.main.file_append(os.path.join(wc_dir, 'A', 'D', 'foo'), "a new file")
 
-  diff_output, err_output = svntest.main.run_svn(1, 'diff',
-                                                 os.path.join(wc_dir,
-                                                              'A', 'D', 'foo'))
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+    1, 'diff', os.path.join(wc_dir, 'A', 'D', 'foo'))
 
   if count_diff_output(diff_output) != 0: raise svntest.Failure
 
@@ -581,28 +583,32 @@
 
   url = sbox.repo_url
 
-  diff_output, err_output = svntest.main.run_svn(None, 'diff', '-c', '2',
-                                                 url)
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            '-c', '2', url)
   if check_update_a_file(diff_output): raise svntest.Failure
 
-  diff_output, err_output = svntest.main.run_svn(None, 'diff', '-r', '1:2')
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            '-r', '1:2')
   if check_update_a_file(diff_output): raise svntest.Failure
 
-  diff_output, err_output = svntest.main.run_svn(None, 'diff', '-c', '3',
-                                                 url)
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            '-c', '3', url)
   if check_add_a_file_in_a_subdir(diff_output): raise svntest.Failure
 
-  diff_output, err_output = svntest.main.run_svn(None, 'diff', '-r', '2:3')
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            '-r', '2:3')
   if check_add_a_file_in_a_subdir(diff_output): raise svntest.Failure
 
-  diff_output, err_output = svntest.main.run_svn(None, 'diff', '-c', '5',
-                                                 url)
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            '-c', '5', url)
   if check_update_added_file(diff_output): raise svntest.Failure
 
-  diff_output, err_output = svntest.main.run_svn(None, 'diff', '-r', '4:5')
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            '-r', '4:5')
   if check_update_added_file(diff_output): raise svntest.Failure
 
-  diff_output, err_output = svntest.main.run_svn(None, 'diff', '-r', 'head')
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            '-r', 'head')
   if check_add_a_file_in_a_subdir_reverse(diff_output): raise svntest.Failure
 
 
@@ -720,7 +726,7 @@
 
   re_nodisplay = re.compile('^Cannot display:')
 
-  stdout, stderr = svntest.main.run_svn(None, 'diff', wc_dir)
+  exit_code, stdout, stderr = svntest.main.run_svn(None, 'diff', wc_dir)
 
   for line in stdout:
     if (re_nodisplay.match(line)):
@@ -731,8 +737,8 @@
   # Second diff use-case: 'svn diff -r1 wc' compares the wc against a
   # the first revision in the repository.
 
-  stdout, stderr = svntest.main.run_svn(None,
-                                        'diff', '-r', '1', wc_dir)
+  exit_code, stdout, stderr = svntest.main.run_svn(None,
+                                                   'diff', '-r', '1', wc_dir)
 
   for line in stdout:
     if (re_nodisplay.match(line)):
@@ -756,8 +762,8 @@
   # Third diff use-case: 'svn diff -r2:3 wc' will compare two
   # repository trees.
 
-  stdout, stderr = svntest.main.run_svn(None,
-                                        'diff', '-r', '2:3', wc_dir)
+  exit_code, stdout, stderr = svntest.main.run_svn(None, 'diff',
+                                                   '-r', '2:3', wc_dir)
 
   for line in stdout:
     if (re_nodisplay.match(line)):
@@ -773,20 +779,18 @@
   non_extant_url = sbox.repo_url + '/A/does_not_exist'
   extant_url = sbox.repo_url + '/A/mu'
 
-  diff_output, err_output = svntest.main.run_svn(1,
-                                                 'diff',
-                                                 '--old', non_extant_url,
-                                                 '--new', extant_url)
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+    1, 'diff', '--old', non_extant_url, '--new', extant_url)
+
   for line in err_output:
     if re.search('was not found in the repository at revision', line):
       break
   else:
     raise svntest.Failure
 
-  diff_output, err_output = svntest.main.run_svn(1,
-                                                 'diff',
-                                                 '--old', extant_url,
-                                                 '--new', non_extant_url)
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+    1, 'diff', '--old', extant_url, '--new', non_extant_url)
+
   for line in err_output:
     if re.search('was not found in the repository at revision', line):
       break
@@ -853,9 +857,8 @@
   # If we run 'svn diff -r 1', we should see diffs that include *both*
   # the rev2 changes and local mods.  That's because the working files
   # are being compared to the repository.
-  diff_output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                        'diff',
-                                                        '-r', '1', wc_dir)
+  exit_code, diff_output, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '-r', '1', wc_dir)
 
   # Makes diff output look the same on all platforms.
   def strip_eols(lines):
@@ -877,9 +880,9 @@
   # If we run 'svn diff -r BASE:1', we should see diffs that only show
   # the rev2 changes and NOT the local mods.  That's because the
   # text-bases are being compared to the repository.
-  diff_output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                        'diff', '-r', 'BASE:1',
-                                                        wc_dir)
+  exit_code, diff_output, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '-r', 'BASE:1', wc_dir)
+
   expected_output_lines = [
     "Index: svn-test-work/working_copies/diff_tests-14/iota\n",
     "===================================================================\n",
@@ -898,9 +901,8 @@
   # For example, we just ran 'svn diff -rBASE:1'.  The output should
   # look exactly the same as 'svn diff -r2:1'.  (If you remove the
   # header commentary)
-  diff_output2, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                         'diff', '-r', '2:1',
-                                                         wc_dir)
+  exit_code, diff_output2, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '-r', '2:1', wc_dir)
 
   diff_output[2:4] = []
   diff_output2[2:4] = []
@@ -909,14 +911,11 @@
     raise svntest.Failure
 
   # and similarly, does 'svn diff -r1:2' == 'svn diff -r1:BASE' ?
-  diff_output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                        'diff',
-                                                        '-r', '1:2', wc_dir)
+  exit_code, diff_output, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '-r', '1:2', wc_dir)
 
-  diff_output2, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                         'diff',
-                                                         '-r', '1:BASE',
-                                                         wc_dir)
+  exit_code, diff_output2, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '-r', '1:BASE', wc_dir)
 
   diff_output[2:4] = []
   diff_output2[2:4] = []
@@ -940,21 +939,17 @@
   # once again, verify that -r1:2 and -r1:BASE look the same, as do
   # -r2:1 and -rBASE:1.  None of these diffs should mention the
   # scheduled addition or deletion.
-  diff_output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                        'diff', '-r',
-                                                        '1:2', wc_dir)
+  exit_code, diff_output, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '-r', '1:2', wc_dir)
 
-  diff_output2, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                         'diff', '-r',
-                                                         '1:BASE', wc_dir)
+  exit_code, diff_output2, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '-r', '1:BASE', wc_dir)
 
-  diff_output3, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                         'diff', '-r',
-                                                         '2:1', wc_dir)
+  exit_code, diff_output3, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '-r', '2:1', wc_dir)
 
-  diff_output4, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                         'diff', '-r',
-                                                         'BASE:1', wc_dir)
+  exit_code, diff_output4, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '-r', 'BASE:1', wc_dir)
 
   diff_output[2:4] = []
   diff_output2[2:4] = []
@@ -1001,13 +996,11 @@
 
   # Now 'svn diff -r3:2' should == 'svn diff -rBASE:2', showing the
   # removal of changes to iota, the adding of mu, and deletion of newfile.
-  diff_output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                        'diff', '-r',
-                                                        '3:2', wc_dir)
+  exit_code, diff_output, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '-r', '3:2', wc_dir)
 
-  diff_output2, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                         'diff', '-r',
-                                                         'BASE:2', wc_dir)
+  exit_code, diff_output2, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '-r', 'BASE:2', wc_dir)
 
   # to do the comparison, remove all output lines starting with +++ or ---
   re_infoline = re.compile('^(\+\+\+|---).*$')
@@ -1098,34 +1091,35 @@
   update_url = sbox.repo_url + '/A/B/E/alpha'
   parent_url = sbox.repo_url + '/A/B/E'
 
-  diff_output, err_output = svntest.main.run_svn(None, 'diff',
-                                                 update_path, add_path)
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            update_path,
+                                                            add_path)
   if check_update_a_file(diff_output) or check_add_a_file(diff_output):
     raise svntest.Failure
 
-  diff_output, err_output = svntest.main.run_svn(None, 'diff',
-                                                 update_path)
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            update_path)
   if check_update_a_file(diff_output) or not check_add_a_file(diff_output):
     raise svntest.Failure
 
-  diff_output, err_output = svntest.main.run_svn(None, 'diff',
-                                                 '--old', parent_path,
-                                                 'alpha', 'theta')
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+    None, 'diff', '--old', parent_path, 'alpha', 'theta')
+
   if check_update_a_file(diff_output) or check_add_a_file(diff_output):
     raise svntest.Failure
 
-  diff_output, err_output = svntest.main.run_svn(None, 'diff',
-                                                 '--old', parent_path,
-                                                 'theta')
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+    None, 'diff', '--old', parent_path, 'theta')
+
   if not check_update_a_file(diff_output) or check_add_a_file(diff_output):
     raise svntest.Failure
 
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'ci', '-m', 'log msg')
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'ci',
+                                                            '-m', 'log msg')
 
-  diff_output, err_output = svntest.main.run_svn(1,
-                                                 'diff', '-r1:2',
-                                                 update_path, add_path)
+  exit_code, diff_output, err_output = svntest.main.run_svn(1, 'diff', '-r1:2',
+                                                            update_path,
+                                                            add_path)
 
   regex = 'svn: Unable to find repository location for \'.*\''
   for line in err_output:
@@ -1134,19 +1128,18 @@
   else:
     raise svntest.Failure
 
-  diff_output, err_output = svntest.main.run_svn(1,
-                                                 'diff', '-r1:2',
-                                                 add_path)
+  exit_code, diff_output, err_output = svntest.main.run_svn(1,
+                                                            'diff', '-r1:2',
+                                                            add_path)
   for line in err_output:
     if re.match(regex, line):
       break
   else:
     raise svntest.Failure
 
-  diff_output, err_output = svntest.main.run_svn(1,
-                                                 'diff', '-r1:2',
-                                                 '--old', parent_path,
-                                                 'alpha', 'theta')
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+    1, 'diff', '-r1:2', '--old', parent_path, 'alpha', 'theta')
+
   regex = 'svn: \'.*\' was not found in the repository'
   for line in err_output:
     if re.match(regex, line):
@@ -1154,10 +1147,9 @@
   else:
     raise svntest.Failure
 
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r1:2',
-                                                 '--old', parent_path,
-                                                 'alpha')
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+    None, 'diff', '-r1:2', '--old', parent_path, 'alpha')
+
   if check_update_a_file(diff_output) or not check_add_a_file(diff_output):
     raise svntest.Failure
 
@@ -1194,39 +1186,36 @@
   # Compare repository file on one branch against repository file on
   # another branch
   rel_path = os.path.join('B', 'E', 'alpha')
-  diff_output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                        'diff',
-                                                        '--old', A_url,
-                                                        '--new', A2_url,
-                                                        rel_path)
+  exit_code, diff_output, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '--old', A_url, '--new', A2_url, rel_path)
+
   verify_expected_output(diff_output, "-foo")
   verify_expected_output(diff_output, "+bar")
 
   # Same again but using whole branch
-  diff_output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                        'diff',
-                                                        '--old', A_url,
-                                                        '--new', A2_url)
+  exit_code, diff_output, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '--old', A_url, '--new', A2_url)
+
   verify_expected_output(diff_output, "-foo")
   verify_expected_output(diff_output, "+bar")
 
   # Compare two repository files on different branches
-  diff_output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                        'diff',
-                                                        A_url + '/B/E/alpha',
-                                                        A2_url + '/B/E/alpha')
+  exit_code, diff_output, err = svntest.actions.run_and_verify_svn(
+    None, None, [],
+    'diff', A_url + '/B/E/alpha', A2_url + '/B/E/alpha')
+
   verify_expected_output(diff_output, "-foo")
   verify_expected_output(diff_output, "+bar")
 
   # Compare two versions of a file on a single branch
-  diff_output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                        'diff',
-                                                        A_url + '/B/E/alpha@2',
-                                                        A_url + '/B/E/alpha@3')
+  exit_code, diff_output, err = svntest.actions.run_and_verify_svn(
+    None, None, [],
+    'diff', A_url + '/B/E/alpha@2', A_url + '/B/E/alpha@3')
+                                                       
   verify_expected_output(diff_output, "+foo")
 
   # Compare identical files on different branches
-  diff_output, err = svntest.actions.run_and_verify_svn(
+  exit_code, diff_output, err = svntest.actions.run_and_verify_svn(
     None, [], [],
     'diff', A_url + '/B/E/alpha@2', A2_url + '/B/E/alpha@3')
 
@@ -1264,20 +1253,19 @@
   # another branch
   A_path = os.path.join(sbox.wc_dir, 'A')
   rel_path = os.path.join('B', 'E', 'alpha')
-  diff_output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                        'diff',
-                                                        '--old', A2_url,
-                                                        '--new', A_path,
-                                                        rel_path)
+  exit_code, diff_output, err = svntest.actions.run_and_verify_svn(
+    None, None, [],
+    'diff', '--old', A2_url, '--new', A_path, rel_path)
+
   verify_expected_output(diff_output, "-bar")
   verify_expected_output(diff_output, "+foo")
   verify_expected_output(diff_output, "+zig")
 
   # Same again but using whole branch
-  diff_output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                        'diff',
-                                                        '--old', A2_url,
-                                                        '--new', A_path)
+  exit_code, diff_output, err = svntest.actions.run_and_verify_svn(
+    None, None, [],
+    'diff', '--old', A2_url, '--new', A_path)
+
   verify_expected_output(diff_output, "-bar")
   verify_expected_output(diff_output, "+foo")
   verify_expected_output(diff_output, "+zig")
@@ -1323,17 +1311,19 @@
 
   # Finally, do a diff between the first and second copies of iota,
   # and verify that we got the expected lines.  And then do it in reverse!
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'diff',
-                                                iota_copy_url, iota_copy2_url)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'diff',
+                                                           iota_copy_url,
+                                                           iota_copy2_url)
 
   verify_expected_output(out, "+bar")
   verify_expected_output(out, "-abcdefg")
   verify_expected_output(out, "-opqrstuv")
 
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'diff',
-                                                iota_copy2_url, iota_copy_url)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'diff',
+                                                           iota_copy2_url,
+                                                           iota_copy_url)
 
   verify_expected_output(out, "-bar")
   verify_expected_output(out, "+abcdefg")
@@ -1358,25 +1348,28 @@
   svntest.main.file_append(iota_path, "\nMore text.\n")
 
   # diff r1:COMMITTED should show the property change but not the local edit.
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'diff',
-                                                '-r1:COMMITTED', iota_path)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'diff',
+                                                           '-r1:COMMITTED',
+                                                           iota_path)
   for line in out:
     if line.find("+More text.") != -1:
       raise svntest.Failure
   verify_expected_output(out, "   + pvalue")
 
   # diff r1:BASE should show the property change but not the local edit.
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'diff', '-r1:BASE', iota_path)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'diff', '-r1:BASE',
+                                                           iota_path)
   for line in out:
     if line.find("+More text.") != -1:
       raise svntest.Failure                   # fails at r7481
   verify_expected_output(out, "   + pvalue")  # fails at r7481
 
   # diff r1:WC should show the local edit as well as the property change.
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'diff', '-r1', iota_path)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'diff', '-r1',
+                                                           iota_path)
   verify_expected_output(out, "+More text.")  # fails at r7481
   verify_expected_output(out, "   + pvalue")
 
@@ -1418,9 +1411,9 @@
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'ci', '-m', 'log msg', prefix_path)
 
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'diff', prefix_url,
-                                                other_prefix_url)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'diff', prefix_url,
+                                                           other_prefix_url)
 
   src = extract_diff_path(out[2])
   dest = extract_diff_path(out[3])
@@ -1456,9 +1449,9 @@
   svntest.main.run_svn(None, 'mv', pi_path, pi2_path)
 
   # Repos->WC diff of the file
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r', '1',
-                                                 pi2_path)
+  exit_code, diff_output, err_output = svntest.main.run_svn(None,
+                                                            'diff', '-r', '1',
+                                                            pi2_path)
 
   if check_diff_output(diff_output,
                        pi2_path,
@@ -1468,9 +1461,8 @@
   svntest.main.file_append(pi2_path, "new pi")
 
   # Repos->WC of the directory
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r', '1',
-                                                 os.path.join('A', 'D'))
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+    None, 'diff', '-r', '1', os.path.join('A', 'D'))
 
   if check_diff_output(diff_output,
                        pi_path,
@@ -1483,8 +1475,8 @@
     raise svntest.Failure
 
   # WC->WC of the file
-  diff_output, err_output = svntest.main.run_svn(None, 'diff',
-                                                 pi2_path)
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            pi2_path)
   if check_diff_output(diff_output,
                        pi2_path,
                        'M') :
@@ -1495,18 +1487,18 @@
                                      'ci', '-m', 'log msg')
 
   # Repos->WC diff of file after the rename.
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r', '1',
-                                                 pi2_path)
+  exit_code, diff_output, err_output = svntest.main.run_svn(None,
+                                                            'diff', '-r', '1',
+                                                            pi2_path)
   if check_diff_output(diff_output,
                        pi2_path,
                        'M') :
     raise svntest.Failure
 
   # Repos->repos diff after the rename.
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r', '2:3',
-                                                 pi2_path)
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            '-r', '2:3',
+                                                            pi2_path)
   if check_diff_output(diff_output,
                        os.path.join('A', 'D', 'pi'),
                        'M') :
@@ -1526,9 +1518,9 @@
   svntest.main.file_write(os.path.join('A', 'D', 'I', 'pi'), "new pi")
 
   # Check a repos->wc diff
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff',
-                                                 os.path.join('A', 'D', 'I', 'pi'))
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+    None, 'diff', os.path.join('A', 'D', 'I', 'pi'))
+
   if check_diff_output(diff_output,
                        os.path.join('A', 'D', 'I', 'pi'),
                        'M') :
@@ -1538,9 +1530,9 @@
                                      'ci', '-m', 'log msg')
 
   # Check repos->wc after commit
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r', '1',
-                                                 os.path.join('A', 'D', 'I', 'pi'))
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+    None, 'diff', '-r', '1', os.path.join('A', 'D', 'I', 'pi'))
+
   if check_diff_output(diff_output,
                        os.path.join('A', 'D', 'I', 'pi'),
                        'M') :
@@ -1549,15 +1541,15 @@
   # Test the diff while within the moved directory
   os.chdir(os.path.join('A','D','I'))
 
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r', '1')
+  exit_code, diff_output, err_output = svntest.main.run_svn(None,
+                                                            'diff', '-r', '1')
 
   if check_diff_output(diff_output, 'pi', 'M') :
     raise svntest.Failure
 
   # Test a repos->repos diff while within the moved directory
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r', '1:2')
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            '-r', '1:2')
 
   if check_diff_output(diff_output, 'pi', 'M') :
     raise svntest.Failure
@@ -1587,8 +1579,8 @@
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'ci', '-m', '')
 
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r2:3', 'A')
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff', 
+                                                            '-r2:3', 'A')
   # Check that the result contains a "-" line.
   verify_expected_output(diff_output, "   - v")
 
@@ -1625,19 +1617,17 @@
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'up', sbox.wc_dir)
 
-  diff_output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                        'diff',
-                                                        '-r', 'prev:head',
-                                                        sbox.wc_dir)
+  exit_code, diff_output, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '-r', 'prev:head', sbox.wc_dir)
+
   verify_expected_output(diff_output, "+bar")
   verify_excluded_output(diff_output, "$Date:")
   verify_excluded_output(diff_output, "$Rev:")
   verify_excluded_output(diff_output, "$Id:")
 
-  diff_output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                        'diff',
-                                                        '-r', 'head:prev',
-                                                        sbox.wc_dir)
+  exit_code, diff_output, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '-r', 'head:prev', sbox.wc_dir)
+
   verify_expected_output(diff_output, "-bar")
   verify_excluded_output(diff_output, "$Date:")
   verify_excluded_output(diff_output, "$Rev:")
@@ -1659,10 +1649,9 @@
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'up', sbox.wc_dir)
 
-  diff_output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                        'diff',
-                                                        '-r', 'prev:head',
-                                                        sbox.wc_dir)
+  exit_code, diff_output, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '-r', 'prev:head', sbox.wc_dir)
+
   # these should show up
   verify_expected_output(diff_output, "+$Id:: ")
   verify_expected_output(diff_output, "-$Id:: ")
@@ -1726,25 +1715,25 @@
 
   re_nodisplay = re.compile('^Cannot display:')
 
-  stdout, stderr = svntest.main.run_svn(None,
-                                        'diff', '-r1:2', iota_path,
-                                        '--force')
+  exit_code, stdout, stderr = svntest.main.run_svn(None,
+                                                   'diff', '-r1:2', iota_path,
+                                                   '--force')
 
   for line in stdout:
     if (re_nodisplay.match(line)):
       raise svntest.Failure
 
-  stdout, stderr = svntest.main.run_svn(None,
-                                        'diff', '-r2:1', iota_path,
-                                        '--force')
+  exit_code, stdout, stderr = svntest.main.run_svn(None,
+                                                   'diff', '-r2:1', iota_path,
+                                                   '--force')
 
   for line in stdout:
     if (re_nodisplay.match(line)):
       raise svntest.Failure
 
-  stdout, stderr = svntest.main.run_svn(None,
-                                        'diff', '-r2:3', iota_path,
-                                        '--force')
+  exit_code, stdout, stderr = svntest.main.run_svn(None,
+                                                   'diff', '-r2:3', iota_path,
+                                                   '--force')
 
   for line in stdout:
     if (re_nodisplay.match(line)):
@@ -1764,8 +1753,9 @@
                                    os.path.join('A', 'D', 'I'))
 
   # Check a repos->wc diff
-  diff_output, err_output = svntest.main.run_svn(None, 'diff',
-                                                 os.path.join('A', 'D'))
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+    None, 'diff', os.path.join('A', 'D'))
+
   if check_diff_output(diff_output,
                        os.path.join('A', 'D', 'G', 'pi'),
                        'D') :
@@ -1779,9 +1769,9 @@
                                      'ci', '-m', 'log msg')
 
   # Check repos->wc after commit
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r', '1',
-                                                 os.path.join('A', 'D'))
+  exit_code, diff_output, err_output = svntest.main.run_svn(
+    None, 'diff', '-r', '1', os.path.join('A', 'D'))
+
   if check_diff_output(diff_output,
                        os.path.join('A', 'D', 'G', 'pi'),
                        'D') :
@@ -1792,8 +1782,8 @@
     raise svntest.Failure
 
   # Test a repos->repos diff after commit
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r', '1:2')
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            '-r', '1:2')
   if check_diff_output(diff_output,
                        os.path.join('A', 'D', 'G', 'pi'),
                        'D') :
@@ -1806,15 +1796,15 @@
   # Test the diff while within the moved directory
   os.chdir(os.path.join('A','D','I'))
 
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r', '1')
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            '-r', '1')
 
   if check_diff_output(diff_output, 'pi', 'A') :
     raise svntest.Failure
 
   # Test a repos->repos diff while within the moved directory
-  diff_output, err_output = svntest.main.run_svn(None,
-                                                 'diff', '-r', '1:2')
+  exit_code, diff_output, err_output = svntest.main.run_svn(None, 'diff',
+                                                            '-r', '1:2')
 
   if check_diff_output(diff_output, 'pi', 'A') :
     raise svntest.Failure
@@ -2328,9 +2318,9 @@
   # a file-delete plus file-add.  The former is currently produced if we
   # explicitly request a diff of the file itself, and the latter if we
   # request a tree diff which just happens to contain the file.
-  out, err = svntest.actions.run_and_verify_svn(None,
-                                                svntest.verify.AnyOutput, [],
-                                                'diff', '-rBASE:1', newfile)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(
+    None, svntest.verify.AnyOutput, [], 'diff', '-rBASE:1', newfile)
+
   if check_diff_output(out, newfile, 'M'):
     raise svntest.Failure
 
@@ -2938,7 +2928,8 @@
   sbox.build()
   iota_path = os.path.join(sbox.wc_dir, 'iota')
   svntest.main.file_append(iota_path, "new text in iota")
-  out, err = svntest.main.run_svn(None, 'diff', '--depth', 'empty', iota_path)
+  exit_code, out, err = svntest.main.run_svn(None, 'diff',
+                                             '--depth', 'empty', iota_path)
   if err:
     raise svntest.Failure
   if len(out) < 4:
Index: subversion/tests/cmdline/getopt_tests.py
===================================================================
--- subversion/tests/cmdline/getopt_tests.py	(revision 29740)
+++ subversion/tests/cmdline/getopt_tests.py	(working copy)
@@ -115,11 +115,12 @@
 
   # special case the 'svn' test so that no extra arguments are added
   if basename != 'svn':
-    actual_stdout, actual_stderr = apply(svntest.main.run_svn, (1,) + varargs)
+    exit_code, actual_stdout, actual_stderr = apply(svntest.main.run_svn,
+                                                    (1,) + varargs)
   else:
-    actual_stdout, actual_stderr = apply(svntest.main.run_command,
-                                         (svntest.main.svn_binary, 1, 0)
-                                         + varargs)
+    exit_code, actual_stdout, actual_stderr = apply(svntest.main.run_command,
+                                                    (svntest.main.svn_binary,
+                                                     1, 0) + varargs)
 
   # Delete and perform search and replaces on the lines from the
   # actual and expected output that may differ between build
Index: subversion/tests/cmdline/import_tests.py
===================================================================
--- subversion/tests/cmdline/import_tests.py	(revision 29740)
+++ subversion/tests/cmdline/import_tests.py	(working copy)
@@ -63,7 +63,7 @@
 
   # import new files into repository
   url = sbox.repo_url
-  output, errput =   svntest.actions.run_and_verify_svn(
+  exit_code, output, errput =   svntest.actions.run_and_verify_svn(
     None, None, [], 'import',
     '-m', 'Log message for new import', xt_path, url)
 
@@ -142,7 +142,7 @@
   # import new dir into repository
   url = sbox.repo_url + '/dir'
 
-  output, errput = svntest.actions.run_and_verify_svn(
+  exit_code, output, errput = svntest.actions.run_and_verify_svn(
     None, None, [], 'import',
     '-m', 'Log message for new import',
     dir_path, url)
@@ -209,7 +209,7 @@
   # import new dir into repository
   url = sbox.repo_url + '/dir'
 
-  output, errput = svntest.actions.run_and_verify_svn(
+  exit_code, output, errput = svntest.actions.run_and_verify_svn(
     None, None, [], 'import',
     '-m', 'Log message for new import', '--no-ignore',
     dir_path, url)
Index: subversion/tests/cmdline/lock_tests.py
===================================================================
--- subversion/tests/cmdline/lock_tests.py	(revision 29740)
+++ subversion/tests/cmdline/lock_tests.py	(working copy)
@@ -247,11 +247,11 @@
 
   # attempt (and fail) to lock file
 
-  # This should give a "iota' is already locked... error.
-  svntest.actions.run_and_verify_svn(None, None,
-                                     ".*already locked",
-                                     'lock',
-                                     '-m', 'trying to break', file_path_b)
+  # This should give a "iota' is already locked... error, but exits 0.
+  svntest.actions.run_and_verify_svn2(None, None,
+                                      ".*already locked", 0,
+                                      'lock',
+                                      '-m', 'trying to break', file_path_b)
 
   svntest.actions.run_and_verify_svn(None, ".*locked by user", [],
                                      'lock', '--force',
@@ -671,8 +671,8 @@
   fname = 'A/foo'
   file_path = os.path.join(sbox.wc_dir, fname)
 
-  output, error = svntest.main.run_svn(1, 'lock',
-                                       '-m', '', file_path)
+  exit_code, output, error = svntest.main.run_svn(1, 'lock',
+                                                  '-m', '', file_path)
 
   error_msg = "foo' is not under version control"
   for line in error:
@@ -704,11 +704,11 @@
                        '-m', '', file_path)
 
   # --- Meanwhile, in our other working copy... ---
-  svntest.actions.run_and_verify_svn(None, None,
-                                     ".*newer version of '/iota' exists",
-                                     'lock',
-                                     '--username', svntest.main.wc_author2,
-                                     '-m', '', file_path_b)
+  svntest.actions.run_and_verify_svn2(None, None,
+                                      ".*newer version of '/iota' exists", 0,
+                                      'lock',
+                                      '--username', svntest.main.wc_author2,
+                                      '-m', '', file_path_b)
 
 #----------------------------------------------------------------------
 # Tests reverting a svn:needs-lock file
@@ -940,12 +940,12 @@
   gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
 
   expected_err = ".*svn: warning: To turn off the svn:needs-lock property,.*"
-  svntest.actions.run_and_verify_svn(None, None, expected_err, 'ps',
-                                     'svn:needs-lock', ' ', gamma_path)
+  svntest.actions.run_and_verify_svn2(None, None, expected_err, 0,
+                                      'ps', 'svn:needs-lock', ' ', gamma_path)
 
   expected_err = ".*svn: warning: To turn off the svn:executable property,.*"
-  svntest.actions.run_and_verify_svn(None, None, expected_err, 'ps',
-                                     'svn:executable', ' ', gamma_path)
+  svntest.actions.run_and_verify_svn2(None, None, expected_err, 0,
+                                      'ps', 'svn:executable', ' ', gamma_path)
 
   # commit
   svntest.actions.run_and_verify_svn(None, None, [], 'commit',
@@ -1016,12 +1016,12 @@
   gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
 
   expected_err = ".*svn: warning: To turn off the svn:needs-lock property,.*"
-  svntest.actions.run_and_verify_svn(None, None, expected_err, 'ps',
-                                     'svn:needs-lock', ' ', gamma_path)
+  svntest.actions.run_and_verify_svn2(None, None, expected_err, 0,
+                                      'ps', 'svn:needs-lock', ' ', gamma_path)
 
   expected_err = ".*svn: warning: To turn off the svn:executable property,.*"
-  svntest.actions.run_and_verify_svn(None, None, expected_err, 'ps',
-                                     'svn:executable', ' ', gamma_path)
+  svntest.actions.run_and_verify_svn2(None, None, expected_err, 0,
+                                     'ps', 'svn:executable', ' ', gamma_path)
 
   # commit
   svntest.actions.run_and_verify_svn(None, None, [], 'commit',
@@ -1120,8 +1120,8 @@
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # Get repository lock token
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'info',
-                                                   file_url)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'info', file_url)
   for line in output:
     if line.find("Lock Token:") != -1:
       repos_lock_token = line[12:]
@@ -1131,8 +1131,9 @@
     raise svntest.Failure
 
   # info with revision option
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'info',
-                                                   file_path, '-r1')
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'info',
+                                                              file_path, '-r1')
 
   for line in output:
     if line.find("Lock Token:") != -1:
@@ -1147,8 +1148,9 @@
     raise svntest.Failure
 
   # info with peg revision
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'info',
-                                                   file_path + '@1')
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'info',
+                                                              file_path + '@1')
   for line in output:
     if line.find("Lock Token:") != -1:
       lock_token = line[12:]
@@ -1185,10 +1187,10 @@
 
   error_msg = ".*Path '/A/B/E/alpha' is already locked by user '" + \
               svntest.main.wc_author2 + "'.*"
-  svntest.actions.run_and_verify_svn(None, None, error_msg,
-                                     'lock',
-                                     '--username', svntest.main.wc_author2,
-                                     alpha_path, gamma_path)
+  svntest.actions.run_and_verify_svn2(None, None, error_msg, 0,
+                                      'lock',
+                                      '--username', svntest.main.wc_author2,
+                                      alpha_path, gamma_path)
   expected_status.tweak('A/D/gamma', writelocked='K')
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
@@ -1201,11 +1203,11 @@
 
   error_msg = "(.*No lock on path '/A/B/lambda'.*)" + \
               "|(.*'A/B/lambda' is not locked.*)"
-  svntest.actions.run_and_verify_svn(None, None, error_msg,
-                                     'unlock',
-                                     '--username', svntest.main.wc_author2,
-                                     '--force',
-                                     iota_path, lambda_path, alpha_path)
+  svntest.actions.run_and_verify_svn2(None, None, error_msg, 0,
+                                      'unlock',
+                                      '--username', svntest.main.wc_author2,
+                                      '--force',
+                                      iota_path, lambda_path, alpha_path)
 
 
   expected_status.tweak('iota', 'A/B/E/alpha', writelocked=None)
@@ -1261,9 +1263,9 @@
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # Get info for old iota at r1. This shouldn't give us any lock info.
-  output, errput = svntest.actions.run_and_verify_svn(None, None, [],
-                                                      'info',
-                                                      fname2, '-r1')
+  exit_code, output, errput = svntest.actions.run_and_verify_svn(
+    None, None, [], 'info', fname2, '-r1')
+
   # Since we want to make sure that there is *no* lock info, to make this
   # more robust, we also check that the info command actually output some info.
   got_url = 0
@@ -1342,10 +1344,9 @@
   # Then, unlocking the WC path should fail.
   # ### The error message returned is actually this, but let's worry about that
   # ### another day...
-  svntest.actions.run_and_verify_svn(None, None,
-                                     ".*((No lock on path)|(400 Bad Request))",
-                                     'unlock',
-                                     file_path)
+  svntest.actions.run_and_verify_svn2(
+    None, None, ".*((No lock on path)|(400 Bad Request))", 0,
+    'unlock', file_path)
 
 #----------------------------------------------------------------------
 # Verify that info shows lock info for locked files with URI-unsafe names
@@ -1397,15 +1398,16 @@
 
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
-  # now try to unlock with user jconstant, should fail.
+  # now try to unlock with user jconstant, should fail but exit 0.
   if sbox.repo_url.startswith("http"):
     expected_err = ".*403 Forbidden.*"
   else:
     expected_err = "svn: warning: User '%s' is trying to use a lock owned by "\
                    "'%s'.*" % (svntest.main.wc_author2, svntest.main.wc_author)
-  svntest.actions.run_and_verify_svn(None, [], expected_err, 'unlock',
-                                     '--username', svntest.main.wc_author2,
-                                     pi_path)
+  svntest.actions.run_and_verify_svn2(None, [], expected_err, 0,
+                                      'unlock',
+                                      '--username', svntest.main.wc_author2,
+                                      pi_path)
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
 
Index: subversion/tests/cmdline/log_tests.py
===================================================================
--- subversion/tests/cmdline/log_tests.py	(revision 29740)
+++ subversion/tests/cmdline/log_tests.py	(working copy)
@@ -617,7 +617,8 @@
 
   os.chdir(sbox.wc_dir)
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'log')
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log')
 
   log_chain = parse_log_output(output)
   check_log_chain(log_chain, range(max_revision, 1 - 1, -1))
@@ -680,7 +681,7 @@
 
   os.chdir(sbox.wc_dir)
 
-  output, err = svntest.actions.run_and_verify_svn(
+  exit_code, output, err = svntest.actions.run_and_verify_svn(
     None, None, [],
     'log', sbox.repo_url, 'A/D/G', 'A/D/H')
 
@@ -710,8 +711,8 @@
   "'svn log wc_target@N'"
   guarantee_repos_and_wc(sbox)
   my_path = os.path.join(sbox.wc_dir, "A", "B", "E", "beta") + "@8"
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'log', my_path)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', my_path)
   check_log_chain(parse_log_output(output), [1])
 
 #----------------------------------------------------------------------
@@ -722,8 +723,8 @@
 
   my_url = sbox.repo_url + "/A/B/E/alpha" + "@8"
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'log', my_url)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', my_url)
   check_log_chain(parse_log_output(output), [3, 1])
 
 #----------------------------------------------------------------------
@@ -779,40 +780,40 @@
                                      'up', wc_dir)
 
   # The full log for mu2 is relatively unsurprising
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'log', mu2_path)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', mu2_path)
   log_chain = parse_log_output(output)
   check_log_chain(log_chain, [6, 5, 2, 1])
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'log', mu2_URL)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', mu2_URL)
   log_chain = parse_log_output(output)
   check_log_chain(log_chain, [6, 5, 2, 1])
 
   # First "oddity", the full log for mu2 doesn't include r3, but the -r3
   # log works!
   peg_mu2_path = mu2_path + "@3"
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'log', '-r', '3',
-                                                   peg_mu2_path)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', '-r', '3',
+                                                              peg_mu2_path)
   log_chain = parse_log_output(output)
   check_log_chain(log_chain, [3])
 
   peg_mu2_URL = mu2_URL + "@3"
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'log', '-r', '3',
-                                                   peg_mu2_URL)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', '-r', '3',
+                                                              peg_mu2_URL)
   log_chain = parse_log_output(output)
   check_log_chain(log_chain, [3])
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'log', '-r', '2',
-                                                   mu2_path)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', '-r', '2',
+                                                              mu2_path)
   log_chain = parse_log_output(output)
   check_log_chain(log_chain, [2])
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'log', '-r', '2',
-                                                   mu2_URL)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', '-r', '2',
+                                                              mu2_URL)
   log_chain = parse_log_output(output)
   check_log_chain(log_chain, [2])
 
@@ -862,8 +863,8 @@
   URL = sbox.repo_url
 
   # run log
-  output, errput = svntest.actions.run_and_verify_svn(None, None, [], 'log',
-                                                      URL)
+  exit_code, output, errput = svntest.actions.run_and_verify_svn(
+    None, None, [], 'log', URL)
 
   # Verify the output contains either the expected fuzzy escape
   # sequence, or the literal control char.
@@ -892,9 +893,9 @@
   date_re = re.compile('<date');
 
   # Ensure that we get a date before we delete the property.
-  output, errput = svntest.actions.run_and_verify_svn(None, None, [],
-                                                      'log', '--xml', '-r1',
-                                                      sbox.wc_dir)
+  exit_code, output, errput = svntest.actions.run_and_verify_svn(
+    None, None, [], 'log', '--xml', '-r1', sbox.wc_dir)
+
   matched = 0
   for line in output:
     if date_re.search(line):
@@ -907,9 +908,9 @@
                                      'pdel', '--revprop', '-r1', 'svn:date',
                                      sbox.wc_dir)
 
-  output, errput = svntest.actions.run_and_verify_svn(None, None, [],
-                                                      'log', '--xml', '-r1',
-                                                      sbox.wc_dir)
+  exit_code, output, errput = svntest.actions.run_and_verify_svn(
+    None, None, [], 'log', '--xml', '-r1', sbox.wc_dir)
+
   for line in output:
     if date_re.search(line):
       raise svntest.Failure("log contains date element when svn:date is empty")
@@ -919,33 +920,33 @@
   "svn log --limit"
   guarantee_repos_and_wc(sbox)
 
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'log', '--limit', '2',
-                                                sbox.repo_url)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'log',
+                                                           '--limit', '2',
+                                                           sbox.repo_url)
   log_chain = parse_log_output(out)
   check_log_chain(log_chain, [9, 8])
 
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'log', '--limit', '2',
-                                                sbox.repo_url,
-                                                'A/B')
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'log',
+                                                           '--limit', '2',
+                                                           sbox.repo_url,
+                                                           'A/B')
   log_chain = parse_log_output(out)
   check_log_chain(log_chain, [9, 6])
 
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'log', '--limit', '2',
-                                                '--revision', '2:HEAD',
-                                                sbox.repo_url,
-                                                'A/B')
+  exit_code, out, err = svntest.actions.run_and_verify_svn(
+    None, None, [],
+    'log', '--limit', '2', '--revision', '2:HEAD', sbox.repo_url, 'A/B')
+                                               
   log_chain = parse_log_output(out)
   check_log_chain(log_chain, [3, 6])
 
   # Use -l instead of --limit to test both option forms.
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'log', '-l', '2',
-                                                '--revision', '1',
-                                                sbox.repo_url,
-                                                'A/B')
+  exit_code, out, err = svntest.actions.run_and_verify_svn(
+    None, None, [],
+    'log', '-l', '2', '--revision', '1', sbox.repo_url, 'A/B')
+
   log_chain = parse_log_output(out)
   check_log_chain(log_chain, [1])
 
@@ -966,8 +967,8 @@
 
   target = os.path.join(sbox.wc_dir, 'A', 'B', 'E', 'beta') + '@BASE'
 
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'log', target)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'log', target)
 
   log_chain = parse_log_output(out)
   check_log_chain(log_chain, [9, 1])
@@ -975,8 +976,8 @@
   svntest.actions.run_and_verify_svn(None, None, [], 'update', '-r', '1',
                                      sbox.wc_dir)
 
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'log', target)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'log', target)
 
   log_chain = parse_log_output(out)
   check_log_chain(log_chain, [1])
@@ -986,9 +987,9 @@
   "run log with verbose output"
   guarantee_repos_and_wc(sbox)
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'log',
-                                                   '-v',
-                                                   sbox.wc_dir)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', '-v',
+                                                              sbox.wc_dir)
 
   log_chain = parse_log_output(output)
   path_counts = [2, 2, 1, 2, 2, 2, 4, 1, 20]
@@ -1110,8 +1111,10 @@
   saved_cwd = os.getcwd()
 
   os.chdir(TRUNK_path)
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'log',
-                                                   '-g', '-r14')
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', '-g',
+                                                              '-r14')
+                                                  
 
   log_chain = parse_log_output(output)
   expected_merges = {
@@ -1121,8 +1124,10 @@
 
   os.chdir(saved_cwd)
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'log',
-                                                   '-g', '-r12', BRANCH_B_path)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', '-g',
+                                                              '-r12', 
+                                                              BRANCH_B_path)
   log_chain = parse_log_output(output)
   expected_merges = {
       12: [], 11 : [12],
@@ -1140,8 +1145,10 @@
   BRANCH_B_path = os.path.join(wc_dir, "branches", "b")
 
   # Run log on a copying revision
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'log',
-                                                   '-g', '-r10', BRANCH_B_path)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', '-g', 
+                                                              '-r10',
+                                                              BRANCH_B_path)
 
   # Parse and check output.  There should be no extra revisions.
   log_chain = parse_log_output(output)
@@ -1159,8 +1166,10 @@
   TRUNK_path = os.path.join(sbox.wc_dir, "trunk")
 
   # Run log on a non-copying revision that adds mergeinfo
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'log',
-                                                   '-g', '-r6', TRUNK_path)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', '-g', 
+                                                              '-r6',
+                                                              TRUNK_path)
 
   # Parse and check output.  There should be one extra revision.
   log_chain = parse_log_output(output)
@@ -1178,8 +1187,9 @@
   XI_path = os.path.join(sbox.wc_dir, "trunk", "A", "xi")
 
   # Run log on a non-copying revision that adds mergeinfo
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'log',
-                                                   '-g', XI_path)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', '-g',
+                                                              XI_path)
 
   # Parse and check output.  There should be one extra revision.
   log_chain = parse_log_output(output)
@@ -1205,8 +1215,9 @@
   guarantee_repos_and_wc(sbox)
   repo_url = sbox.repo_url
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'log',
-                                                   '-c', 4, repo_url)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', '-c',
+                                                              4, repo_url)
   log_chain = parse_log_output(output)
   check_log_chain(log_chain, [4])
 
@@ -1216,8 +1227,9 @@
   guarantee_repos_and_wc(sbox)
   repo_url = sbox.repo_url
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'log',
-                                                   '-c', '2:5', repo_url)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', '-c',
+                                                              '2:5', repo_url)
 
   log_chain = parse_log_output(output)
   check_log_chain(log_chain, [2, 3, 4, 5])
@@ -1228,8 +1240,10 @@
   guarantee_repos_and_wc(sbox)
   repo_url = sbox.repo_url
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'log',
-                                                   '-c', '2,5,7', repo_url)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'log', '-c',
+                                                              '2,5,7',
+                                                              repo_url)
 
   log_chain = parse_log_output(output)
   check_log_chain(log_chain, [2, 5, 7])
Index: subversion/tests/cmdline/merge_tests.py
===================================================================
--- subversion/tests/cmdline/merge_tests.py	(revision 29740)
+++ subversion/tests/cmdline/merge_tests.py	(working copy)
@@ -825,8 +825,8 @@
   svntest.actions.run_and_verify_svn(None, [], [], 'merge', '-r', '3:4',
                                      alpha_url, alpha_path)
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'pl', alpha_path)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'pl', alpha_path)
 
   saw_foo = 0
   saw_bar = 0
Index: subversion/tests/cmdline/prop_tests.py
===================================================================
--- subversion/tests/cmdline/prop_tests.py	(revision 29740)
+++ subversion/tests/cmdline/prop_tests.py	(working copy)
@@ -758,10 +758,9 @@
   svntest.main.run_svn(None, 'cp', new_path1, new_path2)
 
   # Check the svn:mime-type
-  actual_stdout, actual_stderr = svntest.main.run_svn(None,
-                                                      'pg',
-                                                      'svn:mime-type',
-                                                      new_path2)
+  actual_exit, actual_stdout, actual_stderr = svntest.main.run_svn(
+    None, 'pg', 'svn:mime-type', new_path2)
+
   expected_stdout = [orig_mime_type + '\n']
   if actual_stdout != expected_stdout:
     print "svn pg svn:mime-type output does not match expected."
@@ -772,10 +771,9 @@
   # Check the svn:executable value.
   # The value of the svn:executable property is now always forced to '*'
   if os.name == 'posix':
-    actual_stdout, actual_stderr = svntest.main.run_svn(None,
-                                                        'pg',
-                                                        'svn:executable',
-                                                        new_path2)
+    actual_exit, actual_stdout, actual_stderr = svntest.main.run_svn(
+      None, 'pg', 'svn:executable', new_path2)
+
     expected_stdout = ['*\n']
     if actual_stdout != expected_stdout:
       print "svn pg svn:executable output does not match expected."
@@ -824,11 +822,8 @@
                                      'propdel', '--revprop', '-r', '0',
                                      'cash-sound', sbox.wc_dir)
 
-  actual_stdout, actual_stderr = svntest.main.run_svn(None,
-                                                      'pg', '--revprop',
-                                                      '-r', '0',
-                                                      'cash-sound',
-                                                      sbox.wc_dir)
+  actual_exit, actual_stdout, actual_stderr = svntest.main.run_svn(
+    None, 'pg', '--revprop', '-r', '0', 'cash-sound', sbox.wc_dir)
 
   # The property should have been deleted.
   regex = 'cha-ching'
@@ -1093,22 +1088,28 @@
   svntest.main.run_svn(None, 'del', '--force', fp_del)
 
   # Test recursive proplist
-  output, errput = svntest.main.run_svn(None, 'proplist', '-R', '-v', wc_dir,
-                                        '-rBASE')
+  exit_code, output, errput = svntest.main.run_svn(None, 'proplist', '-R',
+                                                   '-v', wc_dir, '-rBASE')
   verify_output([ 'old-del', 'old-keep', 'Properties on ', 'Properties on ' ],
                 output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
-  output, errput = svntest.main.run_svn(None, 'proplist', '-R', '-v', wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, 'proplist', '-R',
+                                                   '-v', wc_dir)
   verify_output([ 'new-add', 'new-keep', 'Properties on ', 'Properties on ' ],
                 output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
   # Test recursive propget
-  output, errput = svntest.main.run_svn(None, 'propget', '-R', 'p', wc_dir,
-                                        '-rBASE')
+  exit_code, output, errput = svntest.main.run_svn(None, 'propget', '-R',
+                                                   'p', wc_dir, '-rBASE')
   verify_output([ 'old-del', 'old-keep' ], output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
-  output, errput = svntest.main.run_svn(None, 'propget', '-R', 'p', wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, 'propget', '-R',
+                                                   'p', wc_dir)
   verify_output([ 'new-add', 'new-keep' ], output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
   # Test recursive propset (issue 1794)
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
@@ -1167,26 +1168,30 @@
                                      'propget', prop1, A_url)
 
   # Test normal proplist
-  output, errput = svntest.main.run_svn(None,
-                                        'proplist', iota_url)
+  exit_code, output, errput = svntest.main.run_svn(None,
+                                                   'proplist', iota_url)
   verify_output([ prop1, prop2, 'Properties on ' ],
                 output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
-  output, errput = svntest.main.run_svn(None,
-                                        'proplist', A_url)
+  exit_code, output, errput = svntest.main.run_svn(None,
+                                                   'proplist', A_url)
   verify_output([ prop1, prop2, 'Properties on ' ],
                 output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
   # Test verbose proplist
-  output, errput = svntest.main.run_svn(None,
-                                        'proplist', '-v', iota_url)
+  exit_code, output, errput = svntest.main.run_svn(None,
+                                                   'proplist', '-v', iota_url)
   verify_output([ prop1 + ' : ' + propval1, prop2 + ' : ' + propval2,
                   'Properties on ' ], output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
-  output, errput = svntest.main.run_svn(None,
-                                        'proplist', '-v', A_url)
+  exit_code, output, errput = svntest.main.run_svn(None,
+                                                   'proplist', '-v', A_url)
   verify_output([ prop1 + ' : ' + propval1, prop2 + ' : ' + propval2,
                   'Properties on ' ], output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
   # Test propedit
   svntest.main.use_editor('foo_to_bar')
@@ -1355,28 +1360,34 @@
                        'ci', '-m', 'log message', wc_dir)
 
   # Test depth-empty proplist.
-  output, errput = svntest.main.run_svn(None, 'proplist', '--depth', 'empty',
-                                        '-v', wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, 'proplist',
+                                                   '--depth', 'empty',
+                                                   '-v', wc_dir)
   verify_output([ 'prop1', 'Properties on ' ],
                 output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
   # Test depth-files proplist.
-  output, errput = svntest.main.run_svn(None, 'proplist', '--depth', 'files',
-                                        '-v', wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, 'proplist',
+                                                   '--depth', 'files',
+                                                   '-v', wc_dir)
   verify_output([ 'prop1', 'prop2', 'Properties on ', 'Properties on ' ],
                 output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
   # Test depth-immediates proplist.
-  output, errput = svntest.main.run_svn(None, 'proplist', '--depth',
-                                        'immediates', '-v', wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, 'proplist', '--depth',
+                                                   'immediates', '-v', wc_dir)
   verify_output([ 'prop1', 'prop2', 'prop3' ] + ['Properties on '] * 3,
                 output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
   # Test depth-infinity proplist.
-  output, errput = svntest.main.run_svn(None, 'proplist', '--depth',
-                                        'infinity', '-v', wc_dir)
+  exit_code, output, errput = svntest.main.run_svn(None, 'proplist', '--depth',
+                                                   'infinity', '-v', wc_dir)
   verify_output([ 'prop1', 'prop2', 'prop3', 'prop4' ] + ['Properties on '] * 4,
                 output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
 #----------------------------------------------------------------------
 
@@ -1398,32 +1409,37 @@
   svntest.main.run_svn(None, 'propset', 'p', 'prop4', mu_path)
 
   # Test depth-empty proplist.
-  output, errput = svntest.main.run_svn(None,
-                                        'proplist', '--depth', 'empty',
-                                        '-v', repo_url)
+  exit_code, output, errput = svntest.main.run_svn(None, 'proplist', 
+                                                   '--depth', 'empty',
+                                                   '-v', repo_url)
   verify_output([ 'prop1', 'Properties on ' ],
                 output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
   # Test depth-files proplist.
-  output, errput = svntest.main.run_svn(None,
-                                        'proplist', '--depth', 'files',
-                                        '-v', repo_url)
+  exit_code, output, errput = svntest.main.run_svn(None, 'proplist', 
+                                                   '--depth', 'files',
+                                                   '-v', repo_url)
   verify_output([ 'prop1', 'prop2', 'Properties on ', 'Properties on ' ],
                 output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
   # Test depth-immediates proplist.
-  output, errput = svntest.main.run_svn(None,
-                                        'proplist', '--depth',
-                                        'immediates', '-v', repo_url)
+  exit_code, output, errput = svntest.main.run_svn(None, 'proplist', 
+                                                   '--depth', 'immediates',
+                                                   '-v', repo_url)
+                                        
   verify_output([ 'prop1', 'prop2', 'prop3' ] + ['Properties on '] * 3,
                 output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
   # Test depth-infinity proplist.
-  output, errput = svntest.main.run_svn(None,
-                                        'proplist', '--depth',
-                                        'infinity', '-v', repo_url)
+  exit_code, output, errput = svntest.main.run_svn(None,
+                                                   'proplist', '--depth',
+                                                   'infinity', '-v', repo_url)
   verify_output([ 'prop1', 'prop2', 'prop3', 'prop4' ] + ['Properties on '] * 4,
                 output, errput)
+  svntest.verify.verify_exit_code(None, exit_code, 0)
 
 #----------------------------------------------------------------------
 
Index: subversion/tests/cmdline/revert_tests.py
===================================================================
--- subversion/tests/cmdline/revert_tests.py	(revision 29740)
+++ subversion/tests/cmdline/revert_tests.py	(working copy)
@@ -450,8 +450,8 @@
   svntest.tree.compare_trees("disk", actual_disk, expected_disk.old_tree())
 
   # Make sure the revert removed the copy from information.
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'info',
-                                                   rho_path)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'info', rho_path)
   for line in output:
     if line.find("Copied") != -1:
       print "Error: Revert didn't get rid of copy from information"
@@ -640,8 +640,8 @@
   mu_path = os.path.join(wc_dir, 'A', 'mu')
 
   # Remember the original text of 'mu'
-  text_r1, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                    'cat', mu_path)
+  exit_code, text_r1, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                               'cat', mu_path)
   # delete mu and replace it with a copy of iota
   svntest.main.run_svn(None, 'rm', mu_path)
   svntest.main.run_svn(None, 'mv', iota_path, mu_path)
Index: subversion/tests/cmdline/schedule_tests.py
===================================================================
--- subversion/tests/cmdline/schedule_tests.py	(revision 29740)
+++ subversion/tests/cmdline/schedule_tests.py	(working copy)
@@ -276,9 +276,10 @@
   epsilon_path = os.path.join(wc_dir, 'A', 'D', 'G', 'epsilon')
   files = [delta_path, zeta_path, epsilon_path]
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'revert',
-                                                   '--recursive', wc_dir)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'revert',
+                                                              '--recursive',
+                                                              wc_dir)
   check_reversion(files, output)
 
 #----------------------------------------------------------------------
@@ -295,9 +296,10 @@
   Z_path = os.path.join(wc_dir, 'A', 'D', 'H', 'Z')
   files = [X_path, Y_path, Z_path]
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'revert',
-                                                   '--recursive', wc_dir)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'revert',
+                                                              '--recursive',
+                                                              wc_dir)
   check_reversion(files, output)
 
 #----------------------------------------------------------------------
@@ -314,9 +316,10 @@
   Z_path = os.path.join(wc_dir, 'A', 'D', 'H', 'Z')
   files = [X_path, Y_path, Z_path]
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'revert',
-                                                   '--recursive', wc_dir)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'revert',
+                                                              '--recursive',
+                                                              wc_dir)
   check_reversion(files, output)
 
 #----------------------------------------------------------------------
@@ -334,9 +337,10 @@
   other_path = os.path.join(wc_dir, 'other_exe')
   files = [all_path, none_path, user_path, group_path, other_path]
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'revert',
-                                                   '--recursive', wc_dir)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'revert',
+                                                              '--recursive',
+                                                              wc_dir)
   check_reversion(files, output)
 
 #----------------------------------------------------------------------
@@ -354,9 +358,10 @@
   omega_path = os.path.join(wc_dir, 'A', 'D', 'H', 'omega')
   files = [iota_path, mu_path, omega_path, rho_path]
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'revert',
-                                                   '--recursive', wc_dir)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'revert',
+                                                              '--recursive', 
+                                                              wc_dir)
   check_reversion(files, output)
 
 #----------------------------------------------------------------------
@@ -379,9 +384,10 @@
   files = [E_path, F_path, H_path,
            alpha_path, beta_path, chi_path, omega_path, psi_path]
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'revert',
-                                                   '--recursive', wc_dir)
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'revert',
+                                                              '--recursive',
+                                                              wc_dir)
   check_reversion(files, output)
 
 
Index: subversion/tests/cmdline/special_tests.py
===================================================================
--- subversion/tests/cmdline/special_tests.py	(revision 29740)
+++ subversion/tests/cmdline/special_tests.py	(working copy)
@@ -57,7 +57,8 @@
     })
 
   # Run a diff and verify that we get the correct output
-  stdout_lines, stderr_lines = svntest.main.run_svn(1, 'diff', wc_dir)
+  exit_code, stdout_lines, stderr_lines = svntest.main.run_svn(1, 'diff',
+                                                               wc_dir)
 
   regex = '^\+link linktarget'
   for line in stdout_lines:
@@ -139,8 +140,9 @@
 
   # And does a commit fail?
   os.chdir(was_cwd)
-  stdout_lines, stderr_lines = svntest.main.run_svn(1, 'ci', '-m',
-                                                    'log msg', wc_dir)
+  exit_code, stdout_lines, stderr_lines = svntest.main.run_svn(1, 'ci', '-m',
+                                                               'log msg',
+                                                               wc_dir)
 
   regex = 'svn: Commit failed'
   for line in stderr_lines:
@@ -163,7 +165,7 @@
 
   # import this symlink into the repository
   url = sbox.repo_url + "/dirA/dirB/new_link"
-  output, errput = svntest.actions.run_and_verify_svn(
+  exit_code, output, errput = svntest.actions.run_and_verify_svn(
     'Import a symlink', None, [], 'import',
     '-m', 'log msg', new_path, url)
 
@@ -290,8 +292,9 @@
 
   # And does a commit fail?
   os.chdir(was_cwd)
-  stdout_lines, stderr_lines = svntest.main.run_svn(1, 'ci', '-m',
-                                                    'log msg', wc_dir)
+  exit_code, stdout_lines, stderr_lines = svntest.main.run_svn(1, 'ci', '-m',
+                                                               'log msg',
+                                                               wc_dir)
 
   regex = 'svn: Commit failed'
   for line in stderr_lines:
@@ -572,8 +575,9 @@
   # I'd expect a failed commit here, but replacing a file locally with a
   # directory seems to make svn think the file is unchanged.
   os.chdir(was_cwd)
-  stdout_lines, stderr_lines = svntest.main.run_svn(1, 'ci', '-m',
-                                                    'log msg', wc_dir)
+  exit_code, stdout_lines, stderr_lines = svntest.main.run_svn(1, 'ci', '-m',
+                                                               'log msg',
+                                                               wc_dir)
   if not (stdout_lines == [] or stderr_lines == []):
     raise svntest.Failure
 
Index: subversion/tests/cmdline/stat_tests.py
===================================================================
--- subversion/tests/cmdline/stat_tests.py	(revision 29740)
+++ subversion/tests/cmdline/stat_tests.py	(working copy)
@@ -119,8 +119,8 @@
   wc_dir = sbox.wc_dir
 
   os.chdir(wc_dir)
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'stat', '-vN')
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'stat', '-vN')
 
   if (len(output) != len(os.listdir("."))):
     raise svntest.Failure
@@ -138,14 +138,16 @@
 
   os.remove('iota')
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'status')
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'status')
   for line in output:
     if not re.match("! +iota", line):
       raise svntest.Failure
 
   # This invocation is for issue #2127.
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'status', '-u', 'iota')
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'status', '-u',
+                                                              'iota')
   found_it = 0
   for line in output:
     if re.match("! +1 +iota", line):
@@ -169,7 +171,8 @@
   os.rename('A', 'iota')
   os.rename('was_iota', 'A')
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'status')
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'status')
   if len(output) != 2:
     raise svntest.Failure
   for line in output:
@@ -181,7 +184,8 @@
   os.remove('A')
   os.mkdir('A')
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'status')
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'status')
   if len(output) != 2:
     raise svntest.Failure
   for line in output:
@@ -193,7 +197,8 @@
   svntest.main.safe_rmtree('iota')
   os.mkdir('iota')
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'status')
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'status')
   if len(output) != 2:
     raise svntest.Failure
   for line in output:
@@ -216,7 +221,8 @@
   svntest.main.safe_rmtree('A/D')
   os.symlink('bar', 'A/D')
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'status')
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'status')
   if len(output) != 2:
     raise svntest.Failure
   for line in output:
@@ -229,7 +235,8 @@
   os.symlink('A/mu', 'iota')
   os.symlink('C', 'A/D')
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [], 'status')
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'status')
   if len(output) != 2:
     raise svntest.Failure
   for line in output:
@@ -254,8 +261,8 @@
   svntest.main.run_svn(None,
                        'up', '-r', '1')
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'status', '-u')
+  exit_code, output, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                              'status', '-u')
 
   # The bug fixed in revision 3686 was a seg fault.  We don't have a
   # reliable way to detect a seg fault here, since we haven't dealt
@@ -318,9 +325,8 @@
 
   os.chdir(wc_dir)
 
-  output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                   'status',
-                                                   'nonexistent-file')
+  exit_code, output, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'status', 'nonexistent-file')
 
   # there should *not* be a status line printed for the nonexistent file
   for line in output:
@@ -435,8 +441,9 @@
   # the -v flag, which we don't want, as this bug never appeared when
   # -v was passed.  So we run status by hand:
   os.chdir(was_cwd)
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'status', '-u', other_wc)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'status', '-u',
+                                                           other_wc)
 
   for line in out:
     if re.match("\\s+\\*.*crontab\\.root$", line):
@@ -497,7 +504,7 @@
   # We don't want a full status tree here, just one line (or two, if
   # the bug is present).  So run status by hand:
   os.chdir(was_cwd)
-  out, err = svntest.actions.run_and_verify_svn(
+  exit_code, out, err = svntest.actions.run_and_verify_svn(
     None, None, [],
     'status', '-u', os.path.join(other_wc, 'newfile'))
 
@@ -552,7 +559,8 @@
 
 def get_last_changed_date(path):
   "get the Last Changed Date for path using svn info"
-  out, err = svntest.actions.run_and_verify_svn(None, None, [], 'info', path)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'info', path)
   for line in out:
     if re.match("^Last Changed Date", line):
       return line
@@ -562,7 +570,8 @@
 # Helper for timestamp_behaviour test
 def get_text_timestamp(path):
   "get the text-time for path using svn info"
-  out, err = svntest.actions.run_and_verify_svn(None, None, [], 'info', path)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'info', path)
   for line in out:
     if re.match("^Text Last Updated", line):
       return line
@@ -672,7 +681,7 @@
 
   os.chdir(new_subdir)
 
-  out, err = svntest.main.run_svn(1, 'st', '..')
+  exit_code, out, err = svntest.main.run_svn(1, 'st', '..')
   for line in err:
     if line.find('svn: warning: \'..\' is not a working copy') != -1:
       break
@@ -772,9 +781,9 @@
   svntest.main.file_append(file_path, "test status --xml\n")
 
   # Retrieve last changed date from svn log
-  output, error = svntest.actions.run_and_verify_svn(None, None, [],
-                                                     'log', file_path,
-                                                     '--xml', '-rHEAD')
+  exit_code, output, error = svntest.actions.run_and_verify_svn(
+    None, None, [], 'log', file_path, '--xml', '-rHEAD')
+
   info_msg = "<date>"
   for line in output:
     if line.find(info_msg) >= 0:
@@ -806,9 +815,10 @@
               "</status>\n",
              ]
 
-  output, error = svntest.actions.run_and_verify_svn(None, None, [],
-                                                     'status', file_path,
-                                                     '--xml', '-u')
+  exit_code, output, error = svntest.actions.run_and_verify_svn(None, None, [],
+                                                                'status',
+                                                                file_path,
+                                                                '--xml', '-u')
 
   for i in range(0, len(output)):
     if output[i] != template[i]:
@@ -845,7 +855,8 @@
   dir = sbox.repo_dir
   expected_err = ["svn: warning: '" + dir + "' is not a working copy\n",
                   "svn: warning: '" + dir + "' is not a working copy\n"]
-  svntest.actions.run_and_verify_svn(None, [], expected_err, "status", dir, dir)
+  svntest.actions.run_and_verify_svn2(None, [], expected_err, 0,
+                                      "status", dir, dir)
 
 #----------------------------------------------------------------------
 
@@ -1034,9 +1045,9 @@
                                      wc_dir)
 
   # Retrieve last changed date from svn log
-  output, error = svntest.actions.run_and_verify_svn(None, None, [],
-                                                     'log', wc_dir,
-                                                     '--xml', '-r1')
+  exit_code, output, error = svntest.actions.run_and_verify_svn(None, None, [],
+                                                                'log', wc_dir,
+                                                                '--xml', '-r1')
 
   info_msg = "<date>"
   for line in output:
@@ -1089,9 +1100,10 @@
           "</target>\n",
           "</status>\n",]
 
-  output, error = svntest.actions.run_and_verify_svn(None, xout, [],
-                                                     'status', wc_dir,
-                                                     '--xml', '-uN')
+  exit_code, output, error = svntest.actions.run_and_verify_svn(None, xout, [],
+                                                                'status',
+                                                                wc_dir,
+                                                                '--xml', '-uN')
 
 # more incoming prop updates.
 def status_update_verbose_with_incoming_props(sbox):
Index: subversion/tests/cmdline/svnadmin_tests.py
===================================================================
--- subversion/tests/cmdline/svnadmin_tests.py	(revision 29740)
+++ subversion/tests/cmdline/svnadmin_tests.py	(working copy)
@@ -70,7 +70,8 @@
 def get_txns(repo_dir):
   "Get the txn names using 'svnadmin lstxns'."
 
-  output_lines, error_lines = svntest.main.run_svnadmin('lstxns', repo_dir)
+  exit_code, output_lines, error_lines = svntest.main.run_svnadmin('lstxns',
+                                                                   repo_dir)
   txns = map(output_lines.strip, output_lines)
 
   # sort, just in case
@@ -88,8 +89,7 @@
   if type(dump) is type(""):
     dump = [ dump ]
 
-  output, errput = \
-          svntest.main.run_command_stdin(
+  exit_code, output, errput = svntest.main.run_command_stdin(
     svntest.main.svnadmin_binary, expected_stderr, 1, dump,
     'load', '--quiet', sbox.repo_dir, *varargs)
 
@@ -276,7 +276,7 @@
   svntest.main.run_svn(None, 'ci', wc_dir, '--quiet',
                        '-m', 'log msg')
 
-  output, errput = svntest.main.run_svnadmin("dump", repo_dir)
+  exit_code, output, errput = svntest.main.run_svnadmin("dump", repo_dir)
   if svntest.verify.compare_and_display_lines(
     "Output of 'svnadmin dump' is unexpected.",
     'STDERR', ["* Dumped revision 0.\n",
@@ -299,14 +299,15 @@
   svntest.main.file_append(os.path.join(Q_path, 'lambda'), 'hello')
   svntest.main.run_svn(None, 'ci', wc_dir, '--quiet',
                        '-m', 'log msg')
-  output, errput = svntest.main.run_svnadmin("dump", repo_dir)
+  exit_code, output, errput = svntest.main.run_svnadmin("dump", repo_dir)
   svntest.verify.compare_and_display_lines(
     "Output of 'svnadmin dump' is unexpected.",
     'STDERR', ["* Dumped revision 0.\n",
                "* Dumped revision 1.\n",
                "* Dumped revision 2.\n"], errput)
 
-  output, errput = svntest.main.run_svnadmin("dump", "-r", "0:HEAD", repo_dir)
+  exit_code, output, errput = svntest.main.run_svnadmin("dump", "-r",
+                                                        "0:HEAD", repo_dir)
   svntest.verify.compare_and_display_lines(
     "Output of 'svnadmin dump' is unexpected.",
     'STDERR', ["* Dumped revision 0.\n",
@@ -320,7 +321,8 @@
 
   sbox.build(create_wc = False)
 
-  output, errput = svntest.main.run_svnadmin("dump", sbox.repo_dir, '--quiet')
+  exit_code, output, errput = svntest.main.run_svnadmin("dump", sbox.repo_dir,
+                                                        '--quiet')
   svntest.verify.compare_and_display_lines(
     "Output of 'svnadmin dump --quiet' is unexpected.",
     'STDERR', [], errput)
@@ -336,16 +338,20 @@
   cwd = os.getcwd()
 
   os.chdir(backup_dir)
-  output, errput = svntest.main.run_svnadmin("hotcopy",
-                                             os.path.join(cwd, sbox.repo_dir),
-                                             '.')
+  exit_code, output, errput = svntest.main.run_svnadmin(
+    "hotcopy", os.path.join(cwd, sbox.repo_dir), '.')
+
   if errput:
     raise svntest.Failure
 
   os.chdir(cwd)
 
-  origout, origerr = svntest.main.run_svnadmin("dump", sbox.repo_dir, '--quiet')
-  backout, backerr = svntest.main.run_svnadmin("dump", backup_dir, '--quiet')
+  exit_code, origout, origerr = svntest.main.run_svnadmin("dump",
+                                                          sbox.repo_dir,
+                                                          '--quiet')
+  exit_code, backout, backerr = svntest.main.run_svnadmin("dump",
+                                                          backup_dir,
+                                                          '--quiet')
   if origerr or backerr or origout != backout:
     raise svntest.Failure
 
@@ -356,8 +362,9 @@
   sbox.build()
 
   backup_dir, backup_url = sbox.add_repo_path('backup')
-  output, errput = svntest.main.run_svnadmin("hotcopy", sbox.repo_dir,
-                                             backup_dir)
+  exit_code, output, errput = svntest.main.run_svnadmin("hotcopy",
+                                                        sbox.repo_dir,
+                                                        backup_dir)
   if errput:
     print "Error: hotcopy failed"
     raise svntest.Failure
@@ -383,9 +390,11 @@
 
   # Try a simple log property modification.
   iota_path = os.path.join(sbox.wc_dir, "iota")
-  output, errput = svntest.main.run_svnadmin("setlog", sbox.repo_dir,
-                                             "-r0", "--bypass-hooks",
-                                             iota_path)
+  exit_code, output, errput = svntest.main.run_svnadmin("setlog",
+                                                        sbox.repo_dir,
+                                                        "-r0",
+                                                        "--bypass-hooks",
+                                                        iota_path)
   if errput:
     print "Error: 'setlog' failed"
     raise svntest.Failure
@@ -401,8 +410,10 @@
   foo_path = os.path.join(sbox.wc_dir, "foo")
   svntest.main.file_write(foo_path, "foo")
 
-  output, errput = svntest.main.run_svnadmin("setrevprop", sbox.repo_dir,
-                                             "-r0", "svn:author", foo_path)
+  exit_code, output, errput = svntest.main.run_svnadmin("setrevprop",
+                                                        sbox.repo_dir,
+                                                        "-r0", "svn:author",
+                                                        foo_path)
   if errput:
     print "Error: 'setrevprop' failed"
     raise svntest.Failure
@@ -425,7 +436,8 @@
                                      'mkdir', '-m', 'log_msg',
                                      chi_url)
 
-  output, errput = svntest.main.run_svnadmin("verify", sbox.repo_dir)
+  exit_code, output, errput = svntest.main.run_svnadmin("verify",
+                                                        sbox.repo_dir)
   svntest.verify.compare_and_display_lines(
     "Error while running 'svnadmin verify'.",
     'STDERR', ["* Verified revision 0.\n",
@@ -557,7 +569,8 @@
 """)
   fp.close()
 
-  output, errput = svntest.main.run_svnadmin("verify", "-r2", sbox.repo_dir)
+  exit_code, output, errput = svntest.main.run_svnadmin("verify", "-r2",
+                                                        sbox.repo_dir)
   svntest.verify.verify_outputs(
     message=None, actual_stdout=output, actual_stderr=errput,
     expected_stdout=None,
@@ -585,7 +598,8 @@
             os.path.join(sbox.repo_dir, 'db','was_current'));
 
   # Run 'svnadmin recover' and check that the current file is recreated.
-  output, errput = svntest.main.run_svnadmin("recover", sbox.repo_dir)
+  exit_code, output, errput = svntest.main.run_svnadmin("recover",
+                                                        sbox.repo_dir)
   if errput:
     raise SVNUnexpectedStderr(errput)
 
@@ -598,7 +612,8 @@
   svntest.main.file_write(current_path, '2\n')
 
   # Run 'svnadmin recover' and check that the current file is fixed.
-  output, errput = svntest.main.run_svnadmin("recover", sbox.repo_dir)
+  exit_code, output, errput = svntest.main.run_svnadmin("recover",
+                                                        sbox.repo_dir)
   if errput:
     raise SVNUnexpectedStderr(errput)
 
@@ -611,7 +626,8 @@
   svntest.main.file_write(current_path, '1\n')
 
   # Run 'svnadmin recover' and check that the current file is fixed.
-  output, errput = svntest.main.run_svnadmin("recover", sbox.repo_dir)
+  exit_code, output, errput = svntest.main.run_svnadmin("recover",
+                                                        sbox.repo_dir)
   if errput:
     raise SVNUnexpectedStderr(errput)
 
@@ -629,7 +645,8 @@
   svntest.main.file_write(current_path, 'fish\n')
 
   # Run 'svnadmin recover' and check that the current file is fixed.
-  output, errput = svntest.main.run_svnadmin("recover", sbox.repo_dir)
+  exit_code, output, errput = svntest.main.run_svnadmin("recover",
+                                                        sbox.repo_dir)
   if errput:
     raise SVNUnexpectedStderr(errput)
 
@@ -682,7 +699,7 @@
   sbox.build(create_wc=False)
 
   # Squirrel away the original repository UUID.
-  output, errput = svntest.main.run_svnlook('uuid', sbox.repo_dir)
+  exit_code, output, errput = svntest.main.run_svnlook('uuid', sbox.repo_dir)
   if errput:
     raise SVNUnexpectedStderr(errput)
   orig_uuid = output[0].rstrip()
@@ -694,7 +711,7 @@
   # Try generating a brand new UUID.
   svntest.actions.run_and_verify_svnadmin(None, [], None,
                                           'setuuid', sbox.repo_dir)
-  output, errput = svntest.main.run_svnlook('uuid', sbox.repo_dir)
+  exit_code, output, errput = svntest.main.run_svnlook('uuid', sbox.repo_dir)
   if errput:
     raise SVNUnexpectedStderr(errput)
   new_uuid = output[0].rstrip()
@@ -705,7 +722,7 @@
   # Now, try setting the UUID back to the original value.
   svntest.actions.run_and_verify_svnadmin(None, [], None,
                                           'setuuid', sbox.repo_dir, orig_uuid)
-  output, errput = svntest.main.run_svnlook('uuid', sbox.repo_dir)
+  exit_code, output, errput = svntest.main.run_svnlook('uuid', sbox.repo_dir)
   if errput:
     raise SVNUnexpectedStderr(errput)
   new_uuid = output[0].rstrip()
@@ -779,7 +796,8 @@
   
   # Verify 'svnadmin recover' fails when youngest has a revprops
   # file but no revs file.
-  output, errput = svntest.main.run_svnadmin("recover", sbox.repo_dir)
+  exit_code, output, errput = svntest.main.run_svnadmin("recover",
+                                                        sbox.repo_dir)
 
   if svntest.verify.verify_outputs(
     "Output of 'svnadmin recover' is unexpected.", None, errput, None,
@@ -796,7 +814,8 @@
 
   # Verify 'svnadmin recover' fails when youngest has a revs file
   # but no revprops file (issue #2992).
-  output, errput = svntest.main.run_svnadmin("recover", sbox.repo_dir)
+  exit_code, output, errput = svntest.main.run_svnadmin("recover",
+                                                        sbox.repo_dir)
 
   if svntest.verify.verify_outputs(
     "Output of 'svnadmin recover' is unexpected.", None, errput, None,
@@ -814,7 +833,8 @@
 
   # Verify 'svnadmin recover' fails when youngest has a revs file
   # but revprops file is not a file (another aspect of issue #2992).
-  output, errput = svntest.main.run_svnadmin("recover", sbox.repo_dir)
+  exit_code, output, errput = svntest.main.run_svnadmin("recover",
+                                                        sbox.repo_dir)
 
   if svntest.verify.verify_outputs(
     "Output of 'svnadmin recover' is unexpected.", None, errput, None,
Index: subversion/tests/cmdline/svndumpfilter_tests.py
===================================================================
--- subversion/tests/cmdline/svndumpfilter_tests.py	(revision 29740)
+++ subversion/tests/cmdline/svndumpfilter_tests.py	(working copy)
@@ -44,9 +44,8 @@
   if type(dump) is type(""):
     dump = [ dump ]
 
-  ## TODO: Should we need to handle errput?
-  output, errput = \
-          svntest.main.run_command_stdin(
+  ## TODO: Should we need to handle errput and exit_code?
+  exit_code, output, errput = svntest.main.run_command_stdin(
     svntest.main.svndumpfilter_binary, None, 1, dump, *varargs)
 
   return output
Index: subversion/tests/cmdline/svnlook_tests.py
===================================================================
--- subversion/tests/cmdline/svnlook_tests.py	(revision 29740)
+++ subversion/tests/cmdline/svnlook_tests.py	(working copy)
@@ -36,8 +36,9 @@
 def run_svnlook(*varargs):
   """Run svnlook with VARARGS, returns stdout as list of lines.
   Raises Failure if any stderr messages."""
-  output, dummy_errput = svntest.main.run_command(svntest.main.svnlook_binary,
-      0, 0, *varargs)
+  exit_code, output, dummy_errput = svntest.main.run_command(
+    svntest.main.svnlook_binary, 0, 0, *varargs)
+
   return output
 
 
@@ -153,8 +154,9 @@
     raise svntest.Failure
 
   prop_name = 'foo:bar-baz-quux'
-  output, errput = svntest.main.run_svnlook('propget', '--revprop', repo_dir,
-                                            prop_name)
+  exit_code, output, errput = svntest.main.run_svnlook('propget',
+                                                       '--revprop', repo_dir,
+                                                       prop_name)
 
   expected_err = "Property '%s' not found on revision " % prop_name
   for line in errput:
@@ -163,8 +165,9 @@
   else:
     raise svntest.main.SVNUnmatchedError
 
-  output, errput = svntest.main.run_svnlook('propget', '-r1', repo_dir,
-                                            prop_name, '/')
+  exit_code, output, errput = svntest.main.run_svnlook('propget',
+                                                       '-r1', repo_dir,
+                                                       prop_name, '/')
 
   expected_err = "Property '%s' not found on path '/' in revision " % prop_name
   for line in errput:
@@ -207,7 +210,8 @@
                                         None,
                                         wc_dir)
 
-  output, errput = svntest.main.run_svnlook("dirs-changed", repo_dir)
+  exit_code, output, errput = svntest.main.run_svnlook("dirs-changed",
+                                                       repo_dir)
   if errput:
     raise svntest.Failure
 
@@ -238,12 +242,10 @@
                                      'ci', '-m', 'log msg', iota_path)
 
   # Grab the diff
-  expected_output, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                            'diff',
-                                                            '-r', 'PREV',
-                                                            iota_path)
+  exit_code, expected_output, err = svntest.actions.run_and_verify_svn(
+    None, None, [], 'diff', '-r', 'PREV', iota_path)
 
-  output, errput = svntest.main.run_svnlook("diff", repo_dir)
+  exit_code, output, errput = svntest.main.run_svnlook("diff", repo_dir)
   if errput:
     raise svntest.Failure
 
@@ -312,7 +314,8 @@
   # load dumpfile with inconsistent newlines into repos.
   svntest.actions.load_repo(sbox, dump_str=dump_str)
 
-  output, errput = svntest.main.run_svnlook("info", sbox.repo_dir, "-r1")
+  exit_code, output, errput = svntest.main.run_svnlook("info",
+                                                       sbox.repo_dir, "-r1")
   if errput:
     raise svntest.Failure
 
@@ -343,13 +346,14 @@
                                         None,
                                         wc_dir)
 
-  output, errput = svntest.main.run_svnlook("changed", repo_dir)
+  exit_code, output, errput = svntest.main.run_svnlook("changed", repo_dir)
   if errput:
     raise svntest.Failure
 
   expect("changed without --copy-info", ["A   A/alpha2\n"], output)
 
-  output, errput = svntest.main.run_svnlook("changed", repo_dir, "--copy-info")
+  exit_code, output, errput = svntest.main.run_svnlook("changed",
+                                                       repo_dir, "--copy-info")
   if errput:
     raise svntest.Failure
 
@@ -493,10 +497,10 @@
                                           wc_dir)
 
     # Grab the diff
-    expected_output, err = \
-        svntest.actions.run_and_verify_svn(None, None, [], 'diff',
-                                           '-r', 'PREV', '-x',
-                                           '--ignore-eol-style', mu_path)
+    exit_code, expected_output, err = svntest.actions.run_and_verify_svn(
+      None, None, [],
+      'diff', '-r', 'PREV', '-x', '--ignore-eol-style', mu_path)
+                                          
 
     output = run_svnlook('diff', '-r', str(rev + 1), '-x',
                          '--ignore-eol-style', repo_dir, '/A/mu')
Index: subversion/tests/cmdline/svnsync_tests.py
===================================================================
--- subversion/tests/cmdline/svnsync_tests.py	(revision 29740)
+++ subversion/tests/cmdline/svnsync_tests.py	(working copy)
@@ -47,7 +47,7 @@
 
 def run_sync(url, expected_error=None):
   "Synchronize the mirror repository with the master"
-  output, errput = svntest.main.run_svnsync(
+  exit_code, output, errput = svntest.main.run_svnsync(
     "synchronize", url,
     "--username", svntest.main.wc_author,
     "--password", svntest.main.wc_passwd)
@@ -67,7 +67,7 @@
 
 def run_copy_revprops(url, expected_error=None):
   "Copy revprops to the mirror repository from the master"
-  output, errput = svntest.main.run_svnsync(
+  exit_code, output, errput = svntest.main.run_svnsync(
     "copy-revprops", url,
     "--username", svntest.main.wc_author,
     "--password", svntest.main.wc_passwd)
@@ -88,7 +88,7 @@
 
 def run_init(dst_url, src_url):
   "Initialize the mirror repository from the master"
-  output, errput = svntest.main.run_svnsync(
+  exit_code, output, errput = svntest.main.run_svnsync(
     "initialize", dst_url, src_url,
     "--username", svntest.main.wc_author,
     "--password", svntest.main.wc_passwd)
@@ -118,7 +118,7 @@
   build_repos(dest_sbox)
 
   # Setup the mirror repository.  Feed it the UUID of the source repository.
-  output, errput = svntest.main.run_svnlook("uuid", sbox.repo_dir)
+  exit_code, output, errput = svntest.main.run_svnlook("uuid", sbox.repo_dir)
   mirror_cfg = ["SVN-fs-dump-format-version: 2\n",
                 "UUID: " + output[0],
                 ]
@@ -406,11 +406,11 @@
     '\n', # log message is stripped
   ]
 
-  out, err = svntest.main.run_svn(None,
-                                  'log',
-                                  '-r', '3',
-                                  '-v',
-                                  dest_sbox.repo_url)
+  exit_code, out, err = svntest.main.run_svn(None,
+                                             'log',
+                                             '-r', '3',
+                                             '-v',
+                                             dest_sbox.repo_url)
 
   if err:
     raise SVNUnexpectedStderr(err)
@@ -531,11 +531,11 @@
     '\n', # log message is stripped
   ]
 
-  out, err = svntest.main.run_svn(None,
-                                  'log',
-                                  '-r', '2',
-                                  '-v',
-                                  dest_sbox.repo_url)
+  exit_code, out, err = svntest.main.run_svn(None,
+                                             'log',
+                                             '-r', '2',
+                                             '-v',
+                                             dest_sbox.repo_url)
 
   if err:
     raise SVNUnexpectedStderr(err)
@@ -633,11 +633,11 @@
     '\n', # log message is stripped
   ]
 
-  out, err = svntest.main.run_svn(None,
-                                  'log',
-                                  '-r', '2',
-                                  '-v',
-                                  dest_sbox.repo_url)
+  exit_code, out, err = svntest.main.run_svn(None,
+                                             'log',
+                                             '-r', '2',
+                                             '-v',
+                                             dest_sbox.repo_url)
 
   if err:
     raise SVNUnexpectedStderr(err)
Index: subversion/tests/cmdline/svnversion_tests.py
===================================================================
--- subversion/tests/cmdline/svnversion_tests.py	(revision 29740)
+++ subversion/tests/cmdline/svnversion_tests.py	(working copy)
@@ -169,9 +169,9 @@
   # Update to get it on disk
   svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
   ext_path = os.path.join(C_path, 'ext')
-  out, err = svntest.actions.run_and_verify_svn(None,
-                                                svntest.verify.AnyOutput, [],
-                                                'info', ext_path)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(
+    None, svntest.verify.AnyOutput, [], 'info', ext_path)
+
   for line in out:
     if line.find('Revision: 1') != -1:
       break
Index: subversion/tests/cmdline/switch_tests.py
===================================================================
--- subversion/tests/cmdline/switch_tests.py	(revision 29740)
+++ subversion/tests/cmdline/switch_tests.py	(working copy)
@@ -504,7 +504,7 @@
                        iota_path)
 
   # log switched file 'iota'
-  output, error = svntest.main.run_svn(None, 'log', iota_path)
+  exit_code, output, error = svntest.main.run_svn(None, 'log', iota_path)
   for line in output:
     if line.find("set prop on switched iota") != -1:
       break
@@ -690,20 +690,20 @@
                                      'switch', '-N', version1_url, wc2_dir)
 
   # Check the URLs of the (not switched) directories.
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'info', wc2_B_dir)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'info', wc2_B_dir)
   if out[1].find('/A/B') == -1:
     print out[1]
     raise svntest.Failure
 
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'info', wc2_C_dir)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'info', wc2_C_dir)
   if out[1].find('/A/C') == -1:
     print out[1]
     raise svntest.Failure
 
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'info', wc2_D_dir)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'info', wc2_D_dir)
   if out[1].find('/A/D') == -1:
     print out[1]
     raise svntest.Failure
@@ -712,14 +712,15 @@
   # ("svn status -u" might be a better check: it fails when newfile's URL
   # is bad, and shows "S" when mu's URL is wrong.)
   # mu: not switched
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'info', wc2_mu_file)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'info', wc2_mu_file)
   if out[2].find('/branch/version1/mu') == -1:
     print out[2]
     raise svntest.Failure
   # newfile: wrong URL
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'info', wc2_new_file)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'info',
+                                                           wc2_new_file)
   if out[2].find('/branch/version1/newfile') == -1:
     print out[2]
     raise svntest.Failure
@@ -743,8 +744,8 @@
 
   # This switch leaves psi unversioned, because of the local mods,
   # then fails because it tries to add a directory of the same name.
-  out, err = svntest.main.run_svn(1, 'switch',
-                                  G_url, H_path)
+  exit_code, out, err = svntest.main.run_svn(1, 'switch',
+                                             G_url, H_path)
   if not err:
     raise svntest.Failure
 
@@ -767,7 +768,8 @@
 
   # There was a bug whereby the failed switch left the wrong URL in
   # the target directory H.  Check for that.
-  out, err = svntest.actions.run_and_verify_svn(None, None, [], 'info', H_path)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'info', H_path)
   for line in out:
     if line.find('URL: ' + G_url) != -1:
       break
@@ -812,14 +814,14 @@
   svntest.main.file_append(A_Z_path, 'Look, Mom, no ... switch success.')
 
   # This switch should fail for reasons of obstruction.
-  out, err = svntest.main.run_svn(1, 'switch',
-                                  C_url, wc_dir)
+  exit_code, out, err = svntest.main.run_svn(1, 'switch',
+                                             C_url, wc_dir)
   if not err:
     raise svntest.Failure
 
   # However, the URL for A should now reflect A/C/A, not something else.
-  out, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                'info', A_path)
+  exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                           'info', A_path)
   if out[1].find('/A/C/A') == -1:
     raise svntest.Failure
 
@@ -853,8 +855,8 @@
                                         None, wc_dir)
 
   svntest.main.file_append(alpha_path, "hello")
-  out, err = svntest.main.run_svn(1,
-                                  'sw', E_url2, E_path)
+  exit_code, out, err = svntest.main.run_svn(1, 'sw', E_url2, E_path)
+
   for line in err:
     if line.find("object of the same name already exists") != -1:
       break
@@ -1086,9 +1088,9 @@
 
   # import the greek tree
   svntest.main.greek_state.write_to_disk(svntest.main.greek_dump_dir)
-  output, errput = svntest.main.run_svn(None, 'import',
-                                '-m', 'Log message for revision 1.',
-                                svntest.main.greek_dump_dir, sbox.repo_url)
+  exit_code, output, errput = svntest.main.run_svn(
+    None, 'import', '-m', 'Log message for revision 1.',
+    svntest.main.greek_dump_dir, sbox.repo_url)
 
   # checkout
   svntest.main.safe_rmtree(wc_dir, 1)
@@ -1259,19 +1261,18 @@
 
   # Make dir A/D/H/I in repos.
   I_url = sbox.repo_url + "/A/D/H/I"
-  so, se = svntest.actions.run_and_verify_svn("Unexpected error during mkdir",
-                                              ['\n', 'Committed revision 2.\n'],
-                                              [],
-                                              "mkdir", I_url,
-                                              "-m", "Log Message")
+  exit_code, so, se = svntest.actions.run_and_verify_svn(
+    "Unexpected error during mkdir",
+    ['\n', 'Committed revision 2.\n'], [],
+    "mkdir", I_url, "-m", "Log Message")
 
   # Make A/D/G/I and co A/D/H/I into it.
   I_path = os.path.join(sbox.wc_dir, 'A', 'D', 'G', 'I')
   os.mkdir(I_path)
-  so, se = svntest.actions.run_and_verify_svn("Unexpected error during co",
-                                              ['Checked out revision 2.\n'],
-                                              [],
-                                              "co", I_url, I_path)
+  exit_code, so, se = svntest.actions.run_and_verify_svn(
+    "Unexpected error during co",
+    ['Checked out revision 2.\n'], [],
+    "co", I_url, I_path)
 
   # Try the forced switch.  A/D/G/I obstructs the dir A/D/G/I coming
   # from the repos.  Normally this isn't a problem, but A/D/G/I is already
Index: subversion/tests/cmdline/update_tests.py
===================================================================
--- subversion/tests/cmdline/update_tests.py	(revision 29740)
+++ subversion/tests/cmdline/update_tests.py	(working copy)
@@ -587,7 +587,8 @@
   # ### TODO: Can't get run_and_verify_update to work here :-( I get
   # the error "Unequal Types: one Node is a file, the other is a
   # directory". Use run_svn and then run_and_verify_status instead
-  stdout_lines, stdout_lines = svntest.main.run_svn(None, 'up', wc_backup)
+  exit_code, stdout_lines, stdout_lines = svntest.main.run_svn(None, 'up',
+                                                               wc_backup)
   if len (stdout_lines) > 0:
     print "update 2 failed"
     raise svntest.Failure
@@ -966,7 +967,7 @@
   # Do the update twice, both should fail.  After the first failure
   # the wc will be marked "incomplete".
   for n in range(2):
-    out, err = svntest.main.run_svn(1, 'up', wc_dir)
+    exit_code, out, err = svntest.main.run_svn(1, 'up', wc_dir)
     for line in err:
       if line.find("an unversioned directory of the same " \
                    "name already exists") != -1:
@@ -976,7 +977,7 @@
 
   # At one stage an obstructed update in an incomplete wc would leave
   # a txn behind
-  out, err = svntest.main.run_svnadmin('lstxns', sbox.repo_dir)
+  exit_code, out, err = svntest.main.run_svnadmin('lstxns', sbox.repo_dir)
   if out or err:
     raise svntest.Failure
 
@@ -1822,8 +1823,9 @@
   url2 = sbox.repo_url + '/A2/mu'
 
   # Remember the original text of the file
-  text_r1, err = svntest.actions.run_and_verify_svn(None, None, [],
-                                                    'cat', '-r1', url)
+  exit_code, text_r1, err = svntest.actions.run_and_verify_svn(None, None, [],
+                                                               'cat', '-r1',
+                                                               url)
 
   # Commit a different version of the file
   svntest.main.file_write(file, "Second revision of 'mu'\n")
@@ -2062,9 +2064,10 @@
   I_url = sbox.repo_url + "/A/C/I"
   os.remove(I_path)
   os.mkdir(I_path)
-  so, se = svntest.actions.run_and_verify_svn("Unexpected error during co",
-                                              ['Checked out revision 2.\n'],
-                                              [], "co", I_url, I_path)
+  exit_code, so, se = svntest.actions.run_and_verify_svn(
+    "Unexpected error during co",
+    ['Checked out revision 2.\n'], [],
+    "co", I_url, I_path)
 
   svntest.actions.run_and_verify_update(C_Path, None, None, None,
                                         ".*Failed to add " + \
