merge heads
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 5e6c40f..5f158b9 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -3,6 +3,7 @@
 import subprocess
 import sys
 import signal
+import io
 import os
 import errno
 import tempfile
@@ -1256,6 +1257,24 @@
                         close_fds=False, pass_fds=(fd, )))
             self.assertIn('overriding close_fds', str(context.warning))
 
+    def test_stdout_stdin_are_single_inout_fd(self):
+        with io.open(os.devnull, "r+") as inout:
+            p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"],
+                                 stdout=inout, stdin=inout)
+            p.wait()
+
+    def test_stdout_stderr_are_single_inout_fd(self):
+        with io.open(os.devnull, "r+") as inout:
+            p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"],
+                                 stdout=inout, stderr=inout)
+            p.wait()
+
+    def test_stderr_stdin_are_single_inout_fd(self):
+        with io.open(os.devnull, "r+") as inout:
+            p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"],
+                                 stderr=inout, stdin=inout)
+            p.wait()
+
     def test_wait_when_sigchild_ignored(self):
         # NOTE: sigchild_ignore.py may not be an effective test on all OSes.
         sigchild_ignore = support.findfile("sigchild_ignore.py",
@@ -1543,4 +1562,4 @@
     support.reap_children()
 
 if __name__ == "__main__":
-    test_main()
+    unittest.main()
diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py
index e369acb..415f12a 100644
--- a/Lib/webbrowser.py
+++ b/Lib/webbrowser.py
@@ -228,15 +228,9 @@
         else:
             # for TTY browsers, we need stdin/out
             inout = None
-        # if possible, put browser in separate process group, so
-        # keyboard interrupts don't affect browser as well as Python
-        setsid = getattr(os, 'setsid', None)
-        if not setsid:
-            setsid = getattr(os, 'setpgrp', None)
-
         p = subprocess.Popen(cmdline, close_fds=True, stdin=inout,
                              stdout=(self.redirect_stdout and inout or None),
-                             stderr=inout, preexec_fn=setsid)
+                             stderr=inout, start_new_session=True)
         if remote:
             # wait five secons. If the subprocess is not finished, the
             # remote invocation has (hopefully) started a new instance.
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c
index 0f85da9..bf10cbb 100644
--- a/Modules/_posixsubprocess.c
+++ b/Modules/_posixsubprocess.c
@@ -99,10 +99,10 @@
     if (p2cread > 2) {
         POSIX_CALL(close(p2cread));
     }
-    if (c2pwrite > 2) {
+    if (c2pwrite > 2 && c2pwrite != p2cread) {
         POSIX_CALL(close(c2pwrite));
     }
-    if (errwrite != c2pwrite && errwrite > 2) {
+    if (errwrite != c2pwrite && errwrite != p2cread && errwrite > 2) {
         POSIX_CALL(close(errwrite));
     }