Fixed gtest_break_on_failure_unittest on Ubuntu 8.04 and Windows
diff --git a/test/gtest_break_on_failure_unittest.py b/test/gtest_break_on_failure_unittest.py
index 88716c9..a295ac4 100755
--- a/test/gtest_break_on_failure_unittest.py
+++ b/test/gtest_break_on_failure_unittest.py
@@ -77,8 +77,11 @@
   """Runs a command; returns 1 if it was killed by a signal, or 0 otherwise.
   """
 
-  exit_code = os.system(command)
-  return os.WIFSIGNALED(exit_code)
+  p = gtest_test_utils.Subprocess(command)
+  if p.terminated_by_signal:
+    return 1
+  else:
+    return 0
 
 
 # The unit test.
@@ -112,11 +115,13 @@
     if flag_value is None:
       flag = ''
     elif flag_value == '0':
-      flag = ' --%s=0' % BREAK_ON_FAILURE_FLAG
+      flag = '--%s=0' % BREAK_ON_FAILURE_FLAG
     else:
-      flag = ' --%s' % BREAK_ON_FAILURE_FLAG
+      flag = '--%s' % BREAK_ON_FAILURE_FLAG
 
-    command = EXE_PATH + flag
+    command = [EXE_PATH]
+    if flag:
+      command.append(flag)
 
     if expect_seg_fault:
       should_or_not = 'should'
@@ -128,7 +133,8 @@
     SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, None)
 
     msg = ('when %s%s, an assertion failure in "%s" %s cause a seg-fault.' %
-           (BREAK_ON_FAILURE_ENV_VAR, env_var_value_msg, command, should_or_not))
+           (BREAK_ON_FAILURE_ENV_VAR, env_var_value_msg, ' '.join(command),
+            should_or_not))
     self.assert_(has_seg_fault == expect_seg_fault, msg)
 
   def testDefaultBehavior(self):
diff --git a/test/gtest_break_on_failure_unittest_.cc b/test/gtest_break_on_failure_unittest_.cc
index f272fdd..84c4a2e 100644
--- a/test/gtest_break_on_failure_unittest_.cc
+++ b/test/gtest_break_on_failure_unittest_.cc
@@ -41,6 +41,9 @@
 
 #include <gtest/gtest.h>
 
+#ifdef GTEST_OS_WINDOWS
+#include <windows.h>
+#endif
 
 namespace {
 
@@ -53,6 +56,11 @@
 
 
 int main(int argc, char **argv) {
+#ifdef GTEST_OS_WINDOWS
+  // Suppresses display of the Windows error dialog upon encountering
+  // a general protection fault (segment violation).
+  SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS);
+#endif
   testing::InitGoogleTest(&argc, argv);
 
   return RUN_ALL_TESTS();
diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py
index a3f0138..8ee99c0 100755
--- a/test/gtest_test_utils.py
+++ b/test/gtest_test_utils.py
@@ -37,6 +37,13 @@
 import sys
 import unittest
 
+try:
+  import subprocess
+  _SUBPROCESS_MODULE_AVAILABLE = True
+except:
+  import popen2
+  _SUBPROCESS_MODULE_AVAILABLE = False
+
 
 # Initially maps a flag to its default value.  After
 # _ParseAndStripGTestFlags() is called, maps a flag to its actual
@@ -116,29 +123,65 @@
       return -1
 
 
-def RunCommandSuppressOutput(command, working_dir=None):
-  """Changes into a specified directory, if provided, and executes a command.
-  Restores the old directory afterwards.
+class Subprocess:
+  def __init__(this, command, working_dir=None):
+    """Changes into a specified directory, if provided, and executes a command.
+    Restores the old directory afterwards. Execution results are returned
+    via the following attributes:
+      terminated_by_sygnal   True iff the child process has been terminated
+                             by a signal.
+      signal                 Sygnal that terminated the child process.
+      exited                 True iff the child process exited normally.
+      exit_code              The code with which the child proces exited.
+      output                 Child process's stdout and stderr output
+                             combined in a string.
 
-  Args:
-    command: A command to run.
-    working_dir: A directory to change into.
-  """
+    Args:
+      command: A command to run.
+      working_dir: A directory to change into.
+    """
 
-  old_dir = None
-  try:
-    if working_dir is not None:
+    # The subprocess module is the preferrable way of running programs
+    # since it is available and behaves consistently on all platforms,
+    # including Windows. But it is only available starting in python 2.4.
+    # In earlier python versions, we revert to the popen2 module, which is
+    # available in python 2.0 and later but doesn't provide required
+    # functionality (Popen4) under Windows. This allows us to support Mac
+    # OS X 10.4 Tiger, which has python 2.3 installed.
+    if _SUBPROCESS_MODULE_AVAILABLE:
+      p = subprocess.Popen(command,
+                           stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
+                           cwd=working_dir, universal_newlines=True)
+      # communicate returns a tuple with the file obect for the child's
+      # output.
+      this.output = p.communicate()[0]
+      this._return_code = p.returncode
+    else:
       old_dir = os.getcwd()
-      os.chdir(working_dir)
-    f = os.popen(command, 'r')
-    f.read()
-    ret_code = f.close()
-  finally:
-    if old_dir is not None:
-      os.chdir(old_dir)
-  if ret_code is None:
-    ret_code = 0
-  return ret_code
+      try:
+        if working_dir is not None:
+          os.chdir(working_dir)
+        p = popen2.Popen4(command)
+        p.tochild.close()
+        this.output = p.fromchild.read()
+        ret_code = p.wait()
+      finally:
+        os.chdir(old_dir)
+      # Converts ret_code to match the semantics of
+      # subprocess.Popen.returncode.
+      if os.WIFSIGNALED(ret_code):
+        this._return_code = -os.WTERMSIG(ret_code)
+      else:  # os.WIFEXITED(ret_code) should return True here.
+        this._return_code = os.WEXITSTATUS(ret_code)
+
+    if this._return_code < 0:
+      this.terminated_by_signal = True
+      this.exited = False
+      this.signal = -this._return_code
+    else:
+      this.terminated_by_signal = False
+      this.exited = True
+      this.exit_code = this._return_code
 
 
 def Main():
diff --git a/test/gtest_xml_outfiles_test.py b/test/gtest_xml_outfiles_test.py
index d5d7266..4ebc15e 100755
--- a/test/gtest_xml_outfiles_test.py
+++ b/test/gtest_xml_outfiles_test.py
@@ -100,11 +100,10 @@
   def _TestOutFile(self, test_name, expected_xml):
     gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(),
                                    test_name)
-    command = "%s --gtest_output=xml:%s" % (gtest_prog_path, self.output_dir_)
-    status = gtest_test_utils.RunCommandSuppressOutput(
-        command,
-        working_dir=tempfile.mkdtemp())
-    self.assertEquals(0, gtest_test_utils.GetExitStatus(status))
+    command = [gtest_prog_path, "--gtest_output=xml:%s" % self.output_dir_]
+    p = gtest_test_utils.Subprocess(command, working_dir=tempfile.mkdtemp())
+    self.assert_(p.exited)
+    self.assertEquals(0, p.exit_code)
 
     # TODO(wan@google.com): libtool causes the built test binary to be
     #   named lt-gtest_xml_outfiles_test_ instead of
diff --git a/test/gtest_xml_output_unittest.py b/test/gtest_xml_output_unittest.py
index c5f9f57..5e0b220 100755
--- a/test/gtest_xml_output_unittest.py
+++ b/test/gtest_xml_output_unittest.py
@@ -131,10 +131,11 @@
       if e.errno != errno.ENOENT:
         raise
 
-    status = gtest_test_utils.RunCommandSuppressOutput(
-        "%s %s=xml" % (gtest_prog_path, GTEST_OUTPUT_FLAG),
-	working_dir=temp_dir)
-    self.assertEquals(0, gtest_test_utils.GetExitStatus(status))
+    p = gtest_test_utils.Subprocess(
+        [gtest_prog_path, "%s=xml" % GTEST_OUTPUT_FLAG],
+        working_dir=temp_dir)
+    self.assert_(p.exited)
+    self.assertEquals(0, p.exit_code)
     self.assert_(os.path.isfile(output_file))
 
 
@@ -150,18 +151,17 @@
     gtest_prog_path = os.path.join(gtest_test_utils.GetBuildDir(),
                                    gtest_prog_name)
 
-    command = ("%s %s=xml:%s" % (gtest_prog_path, GTEST_OUTPUT_FLAG, xml_path))
-    status = gtest_test_utils.RunCommandSuppressOutput(command)
-    if os.WIFSIGNALED(status):
-      signal = os.WTERMSIG(status)
+    command = [gtest_prog_path, "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path)]
+    p = gtest_test_utils.Subprocess(command)
+    if p.terminated_by_signal:
       self.assert_(False,
-                   "%s was killed by signal %d" % (gtest_prog_name, signal))
+                   "%s was killed by signal %d" % (gtest_prog_name, p.signal))
     else:
-      exit_code = gtest_test_utils.GetExitStatus(status)
-      self.assertEquals(expected_exit_code, exit_code,
+      self.assert_(p.exited)
+      self.assertEquals(expected_exit_code, p.exit_code,
                         "'%s' exited with code %s, which doesn't match "
                         "the expected exit code %s."
-                        % (command, exit_code, expected_exit_code))
+                        % (command, p.exit_code, expected_exit_code))
 
     expected = minidom.parseString(expected_xml)
     actual   = minidom.parse(xml_path)