comparison Python/pythonrun.c @ 43841:ccceaec11442

Fix for #1415 pythonw.exe fails because std streams a missing After a long discussion about the problem with Windows GUI apps Guido decided that sys.stdin, stdout and stderr should be None when the C runtime library returns invalid file descriptors for the standard streams. So far the only known cases are Windows GUI apps and scripts started with pythonw on Windows. The OS restrictions are tight enough to catch the problem on other OSes.
author Christian Heimes <christian@cheimes.de>
date Tue, 13 Nov 2007 02:19:40 +0000
parents 0d462d789b18
children 241281123fd8
comparison
equal deleted inserted replaced
43840:73c8e27eb9ce 43841:ccceaec11442
715 { 715 {
716 PyObject *iomod = NULL, *wrapper; 716 PyObject *iomod = NULL, *wrapper;
717 PyObject *bimod = NULL; 717 PyObject *bimod = NULL;
718 PyObject *m; 718 PyObject *m;
719 PyObject *std = NULL; 719 PyObject *std = NULL;
720 int status = 0; 720 int status = 0, fd;
721 721
722 /* Hack to avoid a nasty recursion issue when Python is invoked 722 /* Hack to avoid a nasty recursion issue when Python is invoked
723 in verbose mode: pre-import the Latin-1 and UTF-8 codecs */ 723 in verbose mode: pre-import the Latin-1 and UTF-8 codecs */
724 if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) { 724 if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) {
725 goto error; 725 goto error;
746 if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) { 746 if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) {
747 goto error; 747 goto error;
748 } 748 }
749 749
750 /* Set sys.stdin */ 750 /* Set sys.stdin */
751 if (!(std = PyFile_FromFd(fileno(stdin), "<stdin>", "r", -1, 751 fd = fileno(stdin);
752 NULL, "\n", 0))) { 752 /* Under some conditions stdin, stdout and stderr may not be connected
753 * and fileno() may point to an invalid file descriptor. For example
754 * GUI apps don't have valid standard streams by default.
755 */
756 if (fd < 0) {
757 #ifdef MS_WINDOWS
758 std = Py_None;
759 Py_INCREF(std);
760 #else
753 goto error; 761 goto error;
754 } 762 #endif
763 }
764 else {
765 if (!(std = PyFile_FromFd(fd, "<stdin>", "r", -1, NULL,
766 "\n", 0))) {
767 goto error;
768 }
769 } /* if (fd < 0) */
755 PySys_SetObject("__stdin__", std); 770 PySys_SetObject("__stdin__", std);
756 PySys_SetObject("stdin", std); 771 PySys_SetObject("stdin", std);
757 Py_DECREF(std); 772 Py_DECREF(std);
758 773
759 /* Set sys.stdout */ 774 /* Set sys.stdout */
760 if (!(std = PyFile_FromFd(fileno(stdout), "<stdout>", "w", -1, 775 fd = fileno(stdout);
761 NULL, "\n", 0))) { 776 if (fd < 0) {
762 goto error; 777 #ifdef MS_WINDOWS
763 } 778 std = Py_None;
779 Py_INCREF(std);
780 #else
781 goto error;
782 #endif
783 }
784 else {
785 if (!(std = PyFile_FromFd(fd, "<stdout>", "w", -1, NULL,
786 "\n", 0))) {
787 goto error;
788 }
789 } /* if (fd < 0) */
764 PySys_SetObject("__stdout__", std); 790 PySys_SetObject("__stdout__", std);
765 PySys_SetObject("stdout", std); 791 PySys_SetObject("stdout", std);
766 Py_DECREF(std); 792 Py_DECREF(std);
767 793
768 #if 1 /* Disable this if you have trouble debugging bootstrap stuff */ 794 #if 1 /* Disable this if you have trouble debugging bootstrap stuff */
769 /* Set sys.stderr, replaces the preliminary stderr */ 795 /* Set sys.stderr, replaces the preliminary stderr */
770 if (!(std = PyFile_FromFd(fileno(stderr), "<stderr>", "w", -1, 796 fd = fileno(stderr);
771 NULL, "\n", 0))) { 797 if (fd < 0) {
772 goto error; 798 #ifdef MS_WINDOWS
773 } 799 std = Py_None;
800 Py_INCREF(std);
801 #else
802 goto error;
803 #endif
804 }
805 else {
806 if (!(std = PyFile_FromFd(fd, "<stderr>", "w", -1, NULL,
807 "\n", 0))) {
808 goto error;
809 }
810 } /* if (fd < 0) */
774 PySys_SetObject("__stderr__", std); 811 PySys_SetObject("__stderr__", std);
775 PySys_SetObject("stderr", std); 812 PySys_SetObject("stderr", std);
776 Py_DECREF(std); 813 Py_DECREF(std);
777 #endif 814 #endif
778 815
779 if (0) { 816 if (0) {
780 error: 817 error:
781 status = -1; 818 status = -1;
782 } 819 }
783 820
784 Py_XDECREF(bimod); 821 Py_XDECREF(bimod);