diff options
author | Guido van Rossum <guido@python.org> | 2007-05-27 09:13:28 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2007-05-27 09:13:28 (GMT) |
commit | eba769657a32cb08d96f021f40c79a54ade0bffc (patch) | |
tree | 08bf65b72163f4c286e61698e4375856d9971cc9 /Python | |
parent | f5bec7c67d5cc05ff1cb91dbc83ead6e0f8e41ec (diff) | |
download | cpython-eba769657a32cb08d96f021f40c79a54ade0bffc.zip cpython-eba769657a32cb08d96f021f40c79a54ade0bffc.tar.gz cpython-eba769657a32cb08d96f021f40c79a54ade0bffc.tar.bz2 |
Make input9) behave properly with the new I/O library.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/bltinmodule.c | 80 |
1 files changed, 66 insertions, 14 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index b292d16..2dc9538 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1571,42 +1571,88 @@ end: string appended after the last value, default a newline."); static PyObject * builtin_input(PyObject *self, PyObject *args) { - PyObject *v = NULL; + PyObject *promptarg = NULL; PyObject *fin = PySys_GetObject("stdin"); PyObject *fout = PySys_GetObject("stdout"); + PyObject *ferr = PySys_GetObject("stderr"); + PyObject *tmp; + long fd; + int tty; - if (!PyArg_UnpackTuple(args, "input", 0, 1, &v)) + /* Parse arguments */ + if (!PyArg_UnpackTuple(args, "input", 0, 1, &promptarg)) return NULL; + /* Check that stdin/out/err are intact */ if (fin == NULL) { - PyErr_SetString(PyExc_RuntimeError, "input: lost sys.stdin"); + PyErr_SetString(PyExc_RuntimeError, + "input(): lost sys.stdin"); return NULL; } if (fout == NULL) { - PyErr_SetString(PyExc_RuntimeError, "input: lost sys.stdout"); + PyErr_SetString(PyExc_RuntimeError, + "input(): lost sys.stdout"); + return NULL; + } + if (ferr == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "input(): lost sys.stderr"); + return NULL; + } + + /* First of all, flush stderr */ + tmp = PyObject_CallMethod(ferr, "flush", ""); + if (tmp == NULL) + return NULL; + Py_DECREF(tmp); + + /* We should only use (GNU) readline if Python's sys.stdin and + sys.stdout are the same as C's stdin and stdout, because we + need to pass it those. */ + tmp = PyObject_CallMethod(fin, "fileno", ""); + if (tmp == NULL) return NULL; + fd = PyInt_AsLong(tmp); + if (fd < 0 && PyErr_Occurred()) + return NULL; + Py_DECREF(tmp); + tty = fd == fileno(stdin) && isatty(fd); + if (tty) { + tmp = PyObject_CallMethod(fout, "fileno", ""); + if (tmp == NULL) + return NULL; + fd = PyInt_AsLong(tmp); + Py_DECREF(tmp); + if (fd < 0 && PyErr_Occurred()) + return NULL; + tty = fd == fileno(stdout) && isatty(fd); } - if (PyFile_AsFile(fin) && PyFile_AsFile(fout) - && isatty(fileno(PyFile_AsFile(fin))) - && isatty(fileno(PyFile_AsFile(fout)))) { + + /* If we're interactive, use (GNU) readline */ + if (tty) { PyObject *po; char *prompt; char *s; PyObject *result; - if (v != NULL) { - po = PyObject_Str(v); + tmp = PyObject_CallMethod(fout, "flush", ""); + if (tmp == NULL) + return NULL; + Py_DECREF(tmp); + if (promptarg != NULL) { + po = PyObject_Str(promptarg); if (po == NULL) return NULL; prompt = PyString_AsString(po); - if (prompt == NULL) + if (prompt == NULL) { + Py_DECREF(po); return NULL; + } } else { po = NULL; prompt = ""; } - s = PyOS_Readline(PyFile_AsFile(fin), PyFile_AsFile(fout), - prompt); + s = PyOS_Readline(stdin, stdout, prompt); Py_XDECREF(po); if (s == NULL) { if (!PyErr_Occurred()) @@ -1631,10 +1677,16 @@ builtin_input(PyObject *self, PyObject *args) PyMem_FREE(s); return result; } - if (v != NULL) { - if (PyFile_WriteObject(v, fout, Py_PRINT_RAW) != 0) + + /* Fallback if we're not interactive */ + if (promptarg != NULL) { + if (PyFile_WriteObject(promptarg, fout, Py_PRINT_RAW) != 0) return NULL; } + tmp = PyObject_CallMethod(fout, "flush", ""); + if (tmp == NULL) + return NULL; + Py_DECREF(tmp); return PyFile_GetLine(fin, -1); } |