Commit 8b6bc442 authored by Martin v. Löwis's avatar Martin v. Löwis

Patch #512981: Update readline input stream on sys.stdin/out change.

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