diff -r cc15d736d860 Lib/test/test_asyncio/test_events.py --- a/Lib/test/test_asyncio/test_events.py Mon Aug 24 20:31:53 2015 -0700 +++ b/Lib/test/test_asyncio/test_events.py Fri Sep 04 13:03:20 2015 +0200 @@ -698,7 +698,8 @@ def test_create_server(self): proto = MyProto(self.loop) - f = self.loop.create_server(lambda: proto, '0.0.0.0', 0) + port = support.find_unused_port() + f = self.loop.create_server(lambda: proto, '0.0.0.0', port) server = self.loop.run_until_complete(f) self.assertEqual(len(server.sockets), 1) sock = server.sockets[0] @@ -1043,7 +1044,8 @@ sock_ob = socket.socket(type=socket.SOCK_STREAM) sock_ob.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock_ob.bind(('0.0.0.0', 0)) + port = support.find_unused_port() + sock_ob.bind(('0.0.0.0', port)) f = self.loop.create_server(TestMyProto, sock=sock_ob) server = self.loop.run_until_complete(f) @@ -1061,7 +1063,8 @@ def test_create_server_addr_in_use(self): sock_ob = socket.socket(type=socket.SOCK_STREAM) sock_ob.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock_ob.bind(('0.0.0.0', 0)) + port = support.find_unused_port() + sock_ob.bind(('0.0.0.0', port)) f = self.loop.create_server(MyProto, sock=sock_ob) server = self.loop.run_until_complete(f) diff -r cc15d736d860 Python/pylifecycle.c --- a/Python/pylifecycle.c Mon Aug 24 20:31:53 2015 -0700 +++ b/Python/pylifecycle.c Fri Sep 04 13:03:20 2015 +0200 @@ -1,4 +1,3 @@ - /* Python interpreter top-level routines, including init/exit */ #include "Python.h" @@ -1076,6 +1075,32 @@ return dummy_fd >= 0; } + +static PyObject* +create_stdio_checked(PyObject* io, + int fd, int write_mode, char* name, + char* encoding, char* errors) +{ + PyObject * std; + + if (!is_valid_fd(fd)) { + std = Py_None; + Py_INCREF(std); + return std; + } + std = create_stdio(io, fd, write_mode, name, encoding, errors); + if (std == NULL) { + /* Protect from a race condition when fd becomes invalid aftter + the first check and before the create_stdio call + */ + if (!is_valid_fd(fd)) { + std = Py_None; + Py_INCREF(std); + } + } + return std; +} + /* Initialize sys.stdin, stdout, stderr and builtins.open */ static int initstdio(void) @@ -1158,30 +1183,18 @@ * and fileno() may point to an invalid file descriptor. For example * GUI apps don't have valid standard streams by default. */ - if (!is_valid_fd(fd)) { - std = Py_None; - Py_INCREF(std); - } - else { - std = create_stdio(iomod, fd, 0, "", encoding, errors); - if (std == NULL) - goto error; - } /* if (fd < 0) */ + std = create_stdio_checked(iomod, fd, 0, "", encoding, errors); + if (std == NULL) + goto error; PySys_SetObject("__stdin__", std); _PySys_SetObjectId(&PyId_stdin, std); Py_DECREF(std); /* Set sys.stdout */ fd = fileno(stdout); - if (!is_valid_fd(fd)) { - std = Py_None; - Py_INCREF(std); - } - else { - std = create_stdio(iomod, fd, 1, "", encoding, errors); - if (std == NULL) - goto error; - } /* if (fd < 0) */ + std = create_stdio_checked(iomod, fd, 1, "", encoding, errors); + if (std == NULL) + goto error; PySys_SetObject("__stdout__", std); _PySys_SetObjectId(&PyId_stdout, std); Py_DECREF(std); @@ -1189,15 +1202,9 @@ #if 1 /* Disable this if you have trouble debugging bootstrap stuff */ /* Set sys.stderr, replaces the preliminary stderr */ fd = fileno(stderr); - if (!is_valid_fd(fd)) { - std = Py_None; - Py_INCREF(std); - } - else { - std = create_stdio(iomod, fd, 1, "", encoding, "backslashreplace"); - if (std == NULL) - goto error; - } /* if (fd < 0) */ + std = create_stdio_checked(iomod, fd, 1, "", encoding, "backslashreplace"); + if (std == NULL) + goto error; /* Same as hack above, pre-import stderr's codec to avoid recursion when import.c tries to write to stderr in verbose mode. */