[Python-checkins] r87651 - python/branches/py3k/Modules/_posixsubprocess.c
gregory.p.smith
python-checkins at python.org
Sun Jan 2 21:52:48 CET 2011
Author: gregory.p.smith
Date: Sun Jan 2 21:52:48 2011
New Revision: 87651
Log:
issue10802: fallback to pipe+fcntl when the pipe2 syscall fails with errno ENOSYS.
Modified:
python/branches/py3k/Modules/_posixsubprocess.c
Modified: python/branches/py3k/Modules/_posixsubprocess.c
==============================================================================
--- python/branches/py3k/Modules/_posixsubprocess.c (original)
+++ python/branches/py3k/Modules/_posixsubprocess.c Sun Jan 2 21:52:48 2011
@@ -415,27 +415,39 @@
Py_BEGIN_ALLOW_THREADS
res = pipe2(fds, O_CLOEXEC);
Py_END_ALLOW_THREADS
-#else
- /* We hold the GIL which offers some protection from other code calling
- * fork() before the CLOEXEC flags have been set but we can't guarantee
- * anything without pipe2(). */
- long oldflags;
-
- res = pipe(fds);
-
- if (res == 0) {
- oldflags = fcntl(fds[0], F_GETFD, 0);
- if (oldflags < 0) res = oldflags;
- }
- if (res == 0)
- res = fcntl(fds[0], F_SETFD, oldflags | FD_CLOEXEC);
-
- if (res == 0) {
- oldflags = fcntl(fds[1], F_GETFD, 0);
- if (oldflags < 0) res = oldflags;
+ if (res != 0 && errno == ENOSYS)
+ {
+ if (PyErr_WarnEx(
+ PyExc_RuntimeWarning,
+ "pipe2 set errno ENOSYS; falling "
+ "back to non-atomic pipe+fcntl.", 1) != 0) {
+ return NULL;
+ }
+ {
+#endif
+ /* We hold the GIL which offers some protection from other code calling
+ * fork() before the CLOEXEC flags have been set but we can't guarantee
+ * anything without pipe2(). */
+ long oldflags;
+
+ res = pipe(fds);
+
+ if (res == 0) {
+ oldflags = fcntl(fds[0], F_GETFD, 0);
+ if (oldflags < 0) res = oldflags;
+ }
+ if (res == 0)
+ res = fcntl(fds[0], F_SETFD, oldflags | FD_CLOEXEC);
+
+ if (res == 0) {
+ oldflags = fcntl(fds[1], F_GETFD, 0);
+ if (oldflags < 0) res = oldflags;
+ }
+ if (res == 0)
+ res = fcntl(fds[1], F_SETFD, oldflags | FD_CLOEXEC);
+#ifdef HAVE_PIPE2
+ }
}
- if (res == 0)
- res = fcntl(fds[1], F_SETFD, oldflags | FD_CLOEXEC);
#endif
if (res != 0)
return PyErr_SetFromErrno(PyExc_OSError);
More information about the Python-checkins
mailing list