]> granicus.if.org Git - python/commitdiff
Patch #512981: Update readline input stream on sys.stdin/out change.
authorMartin v. Löwis <martin@v.loewis.de>
Sat, 26 Oct 2002 14:39:10 +0000 (14:39 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Sat, 26 Oct 2002 14:39:10 +0000 (14:39 +0000)
Include/pythonrun.h
Modules/readline.c
Parser/myreadline.c
Parser/tokenizer.c
Python/bltinmodule.c

index 98965b52a66297ae4ae2088b8e48834d78ce7162..7bc011b1d231b8475f763ddd1cead4428b1b8855 100644 (file)
@@ -113,9 +113,9 @@ PyAPI_FUNC(void) PyFloat_Fini(void);
 PyAPI_FUNC(void) PyOS_FiniInterrupts(void);
 
 /* Stuff with no proper home (yet) */
-PyAPI_FUNC(char *) PyOS_Readline(char *);
+PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, char *);
 PyAPI_DATA(int) (*PyOS_InputHook)(void);
-PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(char *);
+PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, char *);
 
 /* Stack size, in "pointers" (so we get extra safety margins
    on 64-bit platforms).  On a 32-bit platform, this translates
index 59ae8eb37d94321c5710e551e0b21845a74d57de..462d52f9b88a5332b3bb75cad25fba931b044a60 100644 (file)
@@ -32,7 +32,7 @@
 
 /* Pointers needed from outside (but not declared in a header file). */
 extern DL_IMPORT(int) (*PyOS_InputHook)(void);
-extern DL_IMPORT(char) *(*PyOS_ReadlineFunctionPointer)(char *);
+extern DL_IMPORT(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *,char *);
 
 
 /* Exported function to send one line to readline's init file parser */
@@ -606,12 +606,12 @@ onintr(int sig)
 /* Wrapper around GNU readline that handles signals differently. */
 
 static char *
-call_readline(char *prompt)
+call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
 {
        size_t n;
        char *p, *q;
        PyOS_sighandler_t old_inthandler;
-       
+        
        old_inthandler = PyOS_setsig(SIGINT, onintr);
        if (setjmp(jbuf)) {
 #ifdef HAVE_SIGRELSE
@@ -622,6 +622,13 @@ call_readline(char *prompt)
                return NULL;
        }
        rl_event_hook = PyOS_InputHook;
+
+        if (sys_stdin != rl_instream || sys_stdout != rl_outstream) {
+                rl_instream = sys_stdin;
+                rl_outstream = sys_stdout;
+                rl_prep_terminal (1);
+        }
+        
        p = readline(prompt);
        PyOS_setsig(SIGINT, old_inthandler);
 
@@ -676,8 +683,7 @@ initreadline(void)
 
        m = Py_InitModule4("readline", readline_methods, doc_module,
                           (PyObject *)NULL, PYTHON_API_VERSION);
-       if (isatty(fileno(stdin))) {
-               PyOS_ReadlineFunctionPointer = call_readline;
-               setup_readline();
-       }
+
+        PyOS_ReadlineFunctionPointer = call_readline;
+        setup_readline();
 }
index 8fe25ecb8fe3c7ffdf9efb39a1b188ef4d4bd863..7b7ef7e2042e00b4f4f82b376b4bf186589cf583 100644 (file)
@@ -87,14 +87,14 @@ my_fgets(char *buf, int len, FILE *fp)
 /* Readline implementation using fgets() */
 
 char *
-PyOS_StdioReadline(char *prompt)
+PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
 {
        size_t n;
        char *p;
        n = 100;
        if ((p = PyMem_MALLOC(n)) == NULL)
                return NULL;
-       fflush(stdout);
+       fflush(sys_stdout);
 #ifndef RISCOS
        if (prompt)
                fprintf(stderr, "%s", prompt);
@@ -107,7 +107,7 @@ PyOS_StdioReadline(char *prompt)
        }
 #endif
        fflush(stderr);
-       switch (my_fgets(p, (int)n, stdin)) {
+       switch (my_fgets(p, (int)n, sys_stdin)) {
        case 0: /* Normal case */
                break;
        case 1: /* Interrupt */
@@ -135,7 +135,7 @@ PyOS_StdioReadline(char *prompt)
                if (incr > INT_MAX) {
                        PyErr_SetString(PyExc_OverflowError, "input line too long");
                }
-               if (my_fgets(p+n, (int)incr, stdin) != 0)
+               if (my_fgets(p+n, (int)incr, sys_stdin) != 0)
                        break;
                n += strlen(p+n);
        }
@@ -148,20 +148,32 @@ PyOS_StdioReadline(char *prompt)
 
    Note: Python expects in return a buffer allocated with PyMem_Malloc. */
 
-char *(*PyOS_ReadlineFunctionPointer)(char *);
+char *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, char *);
 
 
 /* Interface used by tokenizer.c and bltinmodule.c */
 
 char *
-PyOS_Readline(char *prompt)
+PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
 {
        char *rv;
+
        if (PyOS_ReadlineFunctionPointer == NULL) {
-                       PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
+                PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
        }
+
        Py_BEGIN_ALLOW_THREADS
-       rv = (*PyOS_ReadlineFunctionPointer)(prompt);
+
+        /* This is needed to handle the unlikely case that the
+         * interpreter is in interactive mode *and* stdin/out are not
+         * a tty.  This can happen, for example if python is run like
+         * this: python -i < test1.py
+         */
+        if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))
+                rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);
+        else
+                rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
+                                                     prompt);
        Py_END_ALLOW_THREADS
        return rv;
 }
index 749a59b68c285b49d98484d159128080f3c4cdf5..8490ae9428d036c14103cf034286e98a9c07f8d1 100644 (file)
@@ -18,7 +18,7 @@
 #include "abstract.h"
 #endif /* PGEN */
 
-extern char *PyOS_Readline(char *);
+extern char *PyOS_Readline(FILE *, FILE *, char *);
 /* Return malloc'ed string including trailing \n;
    empty malloc'ed string for EOF;
    NULL if interrupted */
@@ -671,7 +671,7 @@ tok_nextc(register struct tok_state *tok)
                        return Py_CHARMASK(*tok->cur++);
                }
                if (tok->prompt != NULL) {
-                       char *new = PyOS_Readline(tok->prompt);
+                       char *new = PyOS_Readline(stdin, stdout, tok->prompt);
                        if (tok->nextprompt != NULL)
                                tok->prompt = tok->nextprompt;
                        if (new == NULL)
index 2387deb667d3b5e3b460b689d21d02f22ef3d8fd..7e7ad2ef60c3c3d12ac1bbbfe6ba2bae6d5fb757 100644 (file)
@@ -1311,8 +1311,9 @@ builtin_raw_input(PyObject *self, PyObject *args)
                if (PyFile_WriteString(" ", fout) != 0)
                        return NULL;
        }
-       if (PyFile_AsFile(fin) == stdin && PyFile_AsFile(fout) == stdout &&
-           isatty(fileno(stdin)) && isatty(fileno(stdout))) {
+       if (PyFile_Check (fin) && PyFile_Check (fout)
+            && isatty(fileno(PyFile_AsFile(fin)))
+            && isatty(fileno(PyFile_AsFile(fout)))) {
                PyObject *po;
                char *prompt;
                char *s;
@@ -1329,7 +1330,8 @@ builtin_raw_input(PyObject *self, PyObject *args)
                        po = NULL;
                        prompt = "";
                }
-               s = PyOS_Readline(prompt);
+               s = PyOS_Readline(PyFile_AsFile (fin), PyFile_AsFile (fout),
+                                  prompt);
                Py_XDECREF(po);
                if (s == NULL) {
                        PyErr_SetNone(PyExc_KeyboardInterrupt);