Kaydet (Commit) 39a73a4c authored tarafından Antoine Pitrou's avatar Antoine Pitrou

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).
......@@ -285,6 +285,45 @@ class CmdLineTest(unittest.TestCase):
rc, out, err = assert_python_ok('-c', code)
self.assertEqual(b'', err)
# Issue #7111: Python should work without standard streams
@unittest.skipIf(os.name != 'posix', "test needs POSIX semantics")
def _test_no_stdio(self, streams):
code = """if 1:
import os, sys
for i, s in enumerate({streams}):
if getattr(sys, s) is not None:
os._exit(i + 1)
os._exit(42)""".format(streams=streams)
def preexec():
if 'stdin' in streams:
os.close(0)
if 'stdout' in streams:
os.close(1)
if 'stderr' in streams:
os.close(2)
p = subprocess.Popen(
[sys.executable, "-E", "-c", code],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
preexec_fn=preexec)
out, err = p.communicate()
self.assertEqual(test.support.strip_python_stderr(err), b'')
self.assertEqual(p.returncode, 42)
def test_no_stdin(self):
self._test_no_stdio(['stdin'])
def test_no_stdout(self):
self._test_no_stdio(['stdout'])
def test_no_stderr(self):
self._test_no_stdio(['stderr'])
def test_no_std_streams(self):
self._test_no_stdio(['stdin', 'stdout', 'stderr'])
def test_main():
test.support.run_unittest(CmdLineTest)
......
......@@ -10,6 +10,10 @@ What's New in Python 3.3 Alpha 1?
Core and Builtins
-----------------
- 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).
- Issue #11849: Ensure that free()d memory arenas are really released
on POSIX systems supporting anonymous memory mappings. Patch by
Charles-François Natali.
......
......@@ -912,6 +912,19 @@ error:
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)
......@@ -971,13 +984,9 @@ initstdio(void)
* 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);
......@@ -990,13 +999,9 @@ initstdio(void)
/* 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);
......@@ -1010,13 +1015,9 @@ initstdio(void)
#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");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment