comparison Python/pythonrun.c @ 50666:b98fe8dc8acd 3.0

Merged revisions 68451 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r68451 | antoine.pitrou | 2009-01-09 19:53:14 +0100 (ven., 09 janv. 2009) | 6 lines Issue #4705: Fix the -u ("unbuffered binary stdout and stderr") command-line flag to work properly. Furthermore, when specifying -u, the text stdout and stderr streams have line-by-line buffering enabled (the default being to buffer arbitrary chunks of data). Patch by Victor Stinner, test by me. ........
author Antoine Pitrou <solipsis@pitrou.net>
date Fri, 09 Jan 2009 19:14:56 +0000
parents 6f30b97148b6
children 9c2bd647b646
comparison
equal deleted inserted replaced
50662:c94f0279fede 50666:b98fe8dc8acd
86 int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */ 86 int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */
87 int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */ 87 int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */
88 int Py_FrozenFlag; /* Needed by getpath.c */ 88 int Py_FrozenFlag; /* Needed by getpath.c */
89 int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */ 89 int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */
90 int Py_NoUserSiteDirectory = 0; /* for -s and site.py */ 90 int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
91 int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
91 92
92 /* PyModule_GetWarningsModule is no longer necessary as of 2.6 93 /* PyModule_GetWarningsModule is no longer necessary as of 2.6
93 since _warnings is builtin. This API should not be used. */ 94 since _warnings is builtin. This API should not be used. */
94 PyObject * 95 PyObject *
95 PyModule_GetWarningsModule(void) 96 PyModule_GetWarningsModule(void)
726 else { 727 else {
727 Py_DECREF(m); 728 Py_DECREF(m);
728 } 729 }
729 } 730 }
730 731
732 static PyObject*
733 create_stdio(PyObject* io,
734 int fd, int write_mode, char* name,
735 char* encoding, char* errors)
736 {
737 PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL;
738 const char* mode;
739 const PyObject *line_buffering;
740 int buffering;
741
742 if (Py_UnbufferedStdioFlag)
743 buffering = 0;
744 else
745 buffering = -1;
746 if (write_mode)
747 mode = "wb";
748 else
749 mode = "rb";
750 buf = PyObject_CallMethod(io, "open", "isiOOOi",
751 fd, mode, buffering,
752 Py_None, Py_None, Py_None, 0);
753 if (buf == NULL)
754 goto error;
755
756 if (!Py_UnbufferedStdioFlag) {
757 raw = PyObject_GetAttrString(buf, "raw");
758 if (raw == NULL)
759 goto error;
760 }
761 else {
762 raw = buf;
763 Py_INCREF(raw);
764 }
765
766 text = PyUnicode_FromString(name);
767 if (text == NULL || PyObject_SetAttrString(raw, "_name", text) < 0)
768 goto error;
769 Py_CLEAR(raw);
770 Py_CLEAR(text);
771
772 if (Py_UnbufferedStdioFlag)
773 line_buffering = Py_True;
774 else
775 line_buffering = Py_False;
776 stream = PyObject_CallMethod(io, "TextIOWrapper", "OsssO",
777 buf, encoding, errors,
778 "\n", line_buffering);
779 Py_CLEAR(buf);
780 if (stream == NULL)
781 goto error;
782
783 if (write_mode)
784 mode = "w";
785 else
786 mode = "r";
787 text = PyUnicode_FromString(mode);
788 if (!text || PyObject_SetAttrString(stream, "mode", text) < 0)
789 goto error;
790 Py_CLEAR(text);
791 return stream;
792
793 error:
794 Py_XDECREF(buf);
795 Py_XDECREF(stream);
796 Py_XDECREF(text);
797 Py_XDECREF(raw);
798 return NULL;
799 }
800
731 /* Initialize sys.stdin, stdout, stderr and builtins.open */ 801 /* Initialize sys.stdin, stdout, stderr and builtins.open */
732 static int 802 static int
733 initstdio(void) 803 initstdio(void)
734 { 804 {
735 PyObject *iomod = NULL, *wrapper; 805 PyObject *iomod = NULL, *wrapper;
792 #else 862 #else
793 goto error; 863 goto error;
794 #endif 864 #endif
795 } 865 }
796 else { 866 else {
797 if (!(std = PyFile_FromFd(fd, "<stdin>", "r", -1, encoding, 867 std = create_stdio(iomod, fd, 0, "<stdin>", encoding, errors);
798 errors, "\n", 0))) { 868 if (std == NULL)
799 goto error; 869 goto error;
800 }
801 } /* if (fd < 0) */ 870 } /* if (fd < 0) */
802 PySys_SetObject("__stdin__", std); 871 PySys_SetObject("__stdin__", std);
803 PySys_SetObject("stdin", std); 872 PySys_SetObject("stdin", std);
804 Py_DECREF(std); 873 Py_DECREF(std);
805 874
812 #else 881 #else
813 goto error; 882 goto error;
814 #endif 883 #endif
815 } 884 }
816 else { 885 else {
817 if (!(std = PyFile_FromFd(fd, "<stdout>", "w", -1, encoding, 886 std = create_stdio(iomod, fd, 1, "<stdout>", encoding, errors);
818 errors, "\n", 0))) { 887 if (std == NULL)
819 goto error; 888 goto error;
820 }
821 } /* if (fd < 0) */ 889 } /* if (fd < 0) */
822 PySys_SetObject("__stdout__", std); 890 PySys_SetObject("__stdout__", std);
823 PySys_SetObject("stdout", std); 891 PySys_SetObject("stdout", std);
824 Py_DECREF(std); 892 Py_DECREF(std);
825 893
833 #else 901 #else
834 goto error; 902 goto error;
835 #endif 903 #endif
836 } 904 }
837 else { 905 else {
838 if (!(std = PyFile_FromFd(fd, "<stderr>", "w", -1, encoding, 906 std = create_stdio(iomod, fd, 1, "<stderr>", encoding, "backslashreplace");
839 "backslashreplace", "\n", 0))) { 907 if (std == NULL)
840 goto error; 908 goto error;
841 }
842 } /* if (fd < 0) */ 909 } /* if (fd < 0) */
843 910
844 /* Same as hack above, pre-import stderr's codec to avoid recursion 911 /* Same as hack above, pre-import stderr's codec to avoid recursion
845 when import.c tries to write to stderr in verbose mode. */ 912 when import.c tries to write to stderr in verbose mode. */
846 encoding_attr = PyObject_GetAttrString(std, "encoding"); 913 encoding_attr = PyObject_GetAttrString(std, "encoding");