Issue #7111: Python can now be run without a stdin, stdout or stderr stream.
It was already the case with Python 2. However, the corresponding
sys module entries are now set to None (instead of an unusable file object).
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index fe92d30..4b0ac13 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -892,6 +892,19 @@
return NULL;
}
+static int
+is_valid_fd(int fd)
+{
+ int dummy_fd;
+ if (fd < 0 || !_PyVerify_fd(fd))
+ return 0;
+ dummy_fd = dup(fd);
+ if (dummy_fd < 0)
+ return 0;
+ close(dummy_fd);
+ return 1;
+}
+
/* Initialize sys.stdin, stdout, stderr and builtins.open */
static int
initstdio(void)
@@ -951,13 +964,9 @@
* and fileno() may point to an invalid file descriptor. For example
* GUI apps don't have valid standard streams by default.
*/
- if (fd < 0) {
-#ifdef MS_WINDOWS
+ if (!is_valid_fd(fd)) {
std = Py_None;
Py_INCREF(std);
-#else
- goto error;
-#endif
}
else {
std = create_stdio(iomod, fd, 0, "<stdin>", encoding, errors);
@@ -970,13 +979,9 @@
/* Set sys.stdout */
fd = fileno(stdout);
- if (fd < 0) {
-#ifdef MS_WINDOWS
+ if (!is_valid_fd(fd)) {
std = Py_None;
Py_INCREF(std);
-#else
- goto error;
-#endif
}
else {
std = create_stdio(iomod, fd, 1, "<stdout>", encoding, errors);
@@ -990,13 +995,9 @@
#if 1 /* Disable this if you have trouble debugging bootstrap stuff */
/* Set sys.stderr, replaces the preliminary stderr */
fd = fileno(stderr);
- if (fd < 0) {
-#ifdef MS_WINDOWS
+ if (!is_valid_fd(fd)) {
std = Py_None;
Py_INCREF(std);
-#else
- goto error;
-#endif
}
else {
std = create_stdio(iomod, fd, 1, "<stderr>", encoding, "backslashreplace");