blob: d7ed357faa383274e33dd00241b071a94c4630e2 [file] [log] [blame]
Guido van Rossum6fa63431993-12-24 10:36:57 +00001
Guido van Rossumfbd64c81997-02-18 21:53:32 +00002/* Readline interface for tokenizer.c and [raw_]input() in bltinmodule.c.
3 By default, or when stdin is not a tty device, we have a super
4 simple my_readline function using fgets.
5 Optionally, we can use the GNU readline library.
Guido van Rossum6fa63431993-12-24 10:36:57 +00006 my_readline() has a different return value from GNU readline():
7 - NULL if an interrupt occurred or if an error occurred
8 - a malloc'ed empty string if EOF was read
9 - a malloc'ed string ending in \n normally
10*/
11
Guido van Rossum8efa47b1998-08-27 19:43:43 +000012#include "Python.h"
Victor Stinner621cebe2018-11-12 16:53:38 +010013#include "pycore_pystate.h"
Mark Hammond2f10cb82002-07-14 23:12:29 +000014#ifdef MS_WINDOWS
15#define WIN32_LEAN_AND_MEAN
16#include "windows.h"
17#endif /* MS_WINDOWS */
Guido van Rossum6fa63431993-12-24 10:36:57 +000018
Michael W. Hudson30ea2f22004-07-07 17:44:12 +000019
Benjamin Peterson0a37a302017-12-31 10:04:13 -080020PyThreadState* _PyOS_ReadlineTState = NULL;
Michael W. Hudson30ea2f22004-07-07 17:44:12 +000021
Michael W. Hudson30ea2f22004-07-07 17:44:12 +000022#include "pythread.h"
23static PyThread_type_lock _PyOS_ReadlineLock = NULL;
Michael W. Hudson30ea2f22004-07-07 17:44:12 +000024
Thomas Wouters23c9e002000-07-22 19:20:54 +000025int (*PyOS_InputHook)(void) = NULL;
Guido van Rossumfbd64c81997-02-18 21:53:32 +000026
27/* This function restarts a fgets() after an EINTR error occurred
Victor Stinner6f7346b2020-06-03 18:28:18 +020028 except if _PyOS_InterruptOccurred() returns true. */
Guido van Rossumfbd64c81997-02-18 21:53:32 +000029
30static int
Victor Stinner6f7346b2020-06-03 18:28:18 +020031my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp)
Guido van Rossumfbd64c81997-02-18 21:53:32 +000032{
Tim Golden9175c3d2012-06-29 18:39:26 +010033#ifdef MS_WINDOWS
Victor Stinner6f7346b2020-06-03 18:28:18 +020034 HANDLE handle;
35 _Py_BEGIN_SUPPRESS_IPH
36 handle = (HANDLE)_get_osfhandle(fileno(fp));
37 _Py_END_SUPPRESS_IPH
38
39 /* bpo-40826: fgets(fp) does crash if fileno(fp) is closed */
40 if (handle == INVALID_HANDLE_VALUE) {
41 return -1; /* EOF */
42 }
Tim Golden9175c3d2012-06-29 18:39:26 +010043#endif
Victor Stinner6f7346b2020-06-03 18:28:18 +020044
Victor Stinner52c950f2011-04-09 15:55:44 +020045 while (1) {
Victor Stinner6f7346b2020-06-03 18:28:18 +020046 if (PyOS_InputHook != NULL) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000047 (void)(PyOS_InputHook)();
Victor Stinner6f7346b2020-06-03 18:28:18 +020048 }
49
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000050 errno = 0;
Victor Stinner4f711012011-05-30 23:46:00 +020051 clearerr(fp);
Victor Stinner6f7346b2020-06-03 18:28:18 +020052 char *p = fgets(buf, len, fp);
53 if (p != NULL) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000054 return 0; /* No error */
Victor Stinner6f7346b2020-06-03 18:28:18 +020055 }
56 int err = errno;
57
Mark Hammond2f10cb82002-07-14 23:12:29 +000058#ifdef MS_WINDOWS
Tim Golden9175c3d2012-06-29 18:39:26 +010059 /* Ctrl-C anywhere on the line or Ctrl-Z if the only character
60 on a line will set ERROR_OPERATION_ABORTED. Under normal
61 circumstances Ctrl-C will also have caused the SIGINT handler
62 to fire which will have set the event object returned by
63 _PyOS_SigintEvent. This signal fires in another thread and
64 is not guaranteed to have occurred before this point in the
65 code.
66
67 Therefore: check whether the event is set with a small timeout.
68 If it is, assume this is a Ctrl-C and reset the event. If it
69 isn't set assume that this is a Ctrl-Z on its own and drop
70 through to check for EOF.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000071 */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000072 if (GetLastError()==ERROR_OPERATION_ABORTED) {
Victor Stinner6f7346b2020-06-03 18:28:18 +020073 HANDLE hInterruptEvent = _PyOS_SigintEvent();
Martin v. Löwisb26a9b12013-01-25 14:25:48 +010074 switch (WaitForSingleObjectEx(hInterruptEvent, 10, FALSE)) {
Tim Golden9175c3d2012-06-29 18:39:26 +010075 case WAIT_OBJECT_0:
76 ResetEvent(hInterruptEvent);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000077 return 1; /* Interrupt */
Tim Golden9175c3d2012-06-29 18:39:26 +010078 case WAIT_FAILED:
79 return -2; /* Error */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000080 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000081 }
Mark Hammond2f10cb82002-07-14 23:12:29 +000082#endif /* MS_WINDOWS */
Victor Stinner6f7346b2020-06-03 18:28:18 +020083
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000084 if (feof(fp)) {
Victor Stinner4755ab02011-05-10 00:19:53 +020085 clearerr(fp);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000086 return -1; /* EOF */
87 }
Victor Stinner6f7346b2020-06-03 18:28:18 +020088
Guido van Rossumfbd64c81997-02-18 21:53:32 +000089#ifdef EINTR
Antoine Pitrouc345ce12011-12-16 12:28:32 +010090 if (err == EINTR) {
Victor Stinner6f7346b2020-06-03 18:28:18 +020091 PyEval_RestoreThread(tstate);
92 int s = PyErr_CheckSignals();
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000093 PyEval_SaveThread();
Victor Stinner6f7346b2020-06-03 18:28:18 +020094
95 if (s < 0) {
96 return 1;
97 }
98 /* try again */
Victor Stinner52c950f2011-04-09 15:55:44 +020099 continue;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000100 }
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000101#endif
Victor Stinner6f7346b2020-06-03 18:28:18 +0200102
103 if (_PyOS_InterruptOccurred(tstate)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 return 1; /* Interrupt */
105 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000106 return -2; /* Error */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000108 /* NOTREACHED */
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000109}
110
Steve Dower39294992016-08-30 21:22:36 -0700111#ifdef MS_WINDOWS
112/* Readline implementation using ReadConsoleW */
113
114extern char _get_console_type(HANDLE handle);
115
116char *
Victor Stinner6f7346b2020-06-03 18:28:18 +0200117_PyOS_WindowsConsoleReadline(PyThreadState *tstate, HANDLE hStdIn)
Steve Dower39294992016-08-30 21:22:36 -0700118{
119 static wchar_t wbuf_local[1024 * 16];
120 const DWORD chunk_size = 1024;
121
122 DWORD n_read, total_read, wbuflen, u8len;
123 wchar_t *wbuf;
124 char *buf = NULL;
125 int err = 0;
126
ValeriyaSinevichce75df32018-07-19 15:34:03 -0700127 n_read = (DWORD)-1;
Steve Dower39294992016-08-30 21:22:36 -0700128 total_read = 0;
129 wbuf = wbuf_local;
130 wbuflen = sizeof(wbuf_local) / sizeof(wbuf_local[0]) - 1;
131 while (1) {
Thomas A Caswell9b9d58f2018-06-28 12:29:44 -0400132 if (PyOS_InputHook != NULL) {
133 (void)(PyOS_InputHook)();
134 }
Steve Dower39294992016-08-30 21:22:36 -0700135 if (!ReadConsoleW(hStdIn, &wbuf[total_read], wbuflen - total_read, &n_read, NULL)) {
136 err = GetLastError();
137 goto exit;
138 }
ValeriyaSinevichce75df32018-07-19 15:34:03 -0700139 if (n_read == (DWORD)-1 && (err = GetLastError()) == ERROR_OPERATION_ABORTED) {
140 break;
141 }
Steve Dower39294992016-08-30 21:22:36 -0700142 if (n_read == 0) {
143 int s;
144 err = GetLastError();
145 if (err != ERROR_OPERATION_ABORTED)
146 goto exit;
147 err = 0;
148 HANDLE hInterruptEvent = _PyOS_SigintEvent();
149 if (WaitForSingleObjectEx(hInterruptEvent, 100, FALSE)
150 == WAIT_OBJECT_0) {
151 ResetEvent(hInterruptEvent);
Victor Stinner6f7346b2020-06-03 18:28:18 +0200152 PyEval_RestoreThread(tstate);
Steve Dower39294992016-08-30 21:22:36 -0700153 s = PyErr_CheckSignals();
Steve Dower39294992016-08-30 21:22:36 -0700154 PyEval_SaveThread();
Victor Stinner6f7346b2020-06-03 18:28:18 +0200155 if (s < 0) {
Steve Dower39294992016-08-30 21:22:36 -0700156 goto exit;
Victor Stinner6f7346b2020-06-03 18:28:18 +0200157 }
Steve Dower39294992016-08-30 21:22:36 -0700158 }
159 break;
160 }
161
162 total_read += n_read;
163 if (total_read == 0 || wbuf[total_read - 1] == L'\n') {
164 break;
165 }
166 wbuflen += chunk_size;
167 if (wbuf == wbuf_local) {
168 wbuf[total_read] = '\0';
169 wbuf = (wchar_t*)PyMem_RawMalloc(wbuflen * sizeof(wchar_t));
Victor Stinner6f7346b2020-06-03 18:28:18 +0200170 if (wbuf) {
Steve Dower39294992016-08-30 21:22:36 -0700171 wcscpy_s(wbuf, wbuflen, wbuf_local);
Victor Stinner6f7346b2020-06-03 18:28:18 +0200172 }
Zackery Spytz4c49da02018-12-07 03:11:30 -0700173 else {
Victor Stinner6f7346b2020-06-03 18:28:18 +0200174 PyEval_RestoreThread(tstate);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700175 PyErr_NoMemory();
Victor Stinner6f7346b2020-06-03 18:28:18 +0200176 PyEval_SaveThread();
Zackery Spytz4c49da02018-12-07 03:11:30 -0700177 goto exit;
178 }
Steve Dower39294992016-08-30 21:22:36 -0700179 }
Zackery Spytz4c49da02018-12-07 03:11:30 -0700180 else {
181 wchar_t *tmp = PyMem_RawRealloc(wbuf, wbuflen * sizeof(wchar_t));
182 if (tmp == NULL) {
Victor Stinner6f7346b2020-06-03 18:28:18 +0200183 PyEval_RestoreThread(tstate);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700184 PyErr_NoMemory();
Victor Stinner6f7346b2020-06-03 18:28:18 +0200185 PyEval_SaveThread();
Zackery Spytz4c49da02018-12-07 03:11:30 -0700186 goto exit;
187 }
188 wbuf = tmp;
189 }
Steve Dower39294992016-08-30 21:22:36 -0700190 }
191
192 if (wbuf[0] == '\x1a') {
193 buf = PyMem_RawMalloc(1);
Victor Stinner6f7346b2020-06-03 18:28:18 +0200194 if (buf) {
Steve Dower39294992016-08-30 21:22:36 -0700195 buf[0] = '\0';
Victor Stinner6f7346b2020-06-03 18:28:18 +0200196 }
Zackery Spytz4c49da02018-12-07 03:11:30 -0700197 else {
Victor Stinner6f7346b2020-06-03 18:28:18 +0200198 PyEval_RestoreThread(tstate);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700199 PyErr_NoMemory();
Victor Stinner6f7346b2020-06-03 18:28:18 +0200200 PyEval_SaveThread();
Zackery Spytz4c49da02018-12-07 03:11:30 -0700201 }
Steve Dower39294992016-08-30 21:22:36 -0700202 goto exit;
203 }
204
Victor Stinner6f7346b2020-06-03 18:28:18 +0200205 u8len = WideCharToMultiByte(CP_UTF8, 0,
206 wbuf, total_read,
207 NULL, 0,
208 NULL, NULL);
Steve Dower39294992016-08-30 21:22:36 -0700209 buf = PyMem_RawMalloc(u8len + 1);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700210 if (buf == NULL) {
Victor Stinner6f7346b2020-06-03 18:28:18 +0200211 PyEval_RestoreThread(tstate);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700212 PyErr_NoMemory();
Victor Stinner6f7346b2020-06-03 18:28:18 +0200213 PyEval_SaveThread();
Zackery Spytz4c49da02018-12-07 03:11:30 -0700214 goto exit;
215 }
Victor Stinner6f7346b2020-06-03 18:28:18 +0200216
217 u8len = WideCharToMultiByte(CP_UTF8, 0,
218 wbuf, total_read,
219 buf, u8len,
220 NULL, NULL);
Steve Dower39294992016-08-30 21:22:36 -0700221 buf[u8len] = '\0';
Benjamin Petersone2e792d2016-09-19 22:17:16 -0700222
Steve Dower39294992016-08-30 21:22:36 -0700223exit:
Victor Stinner6f7346b2020-06-03 18:28:18 +0200224 if (wbuf != wbuf_local) {
Steve Dower39294992016-08-30 21:22:36 -0700225 PyMem_RawFree(wbuf);
Victor Stinner6f7346b2020-06-03 18:28:18 +0200226 }
Steve Dower39294992016-08-30 21:22:36 -0700227
228 if (err) {
Victor Stinner6f7346b2020-06-03 18:28:18 +0200229 PyEval_RestoreThread(tstate);
Steve Dower39294992016-08-30 21:22:36 -0700230 PyErr_SetFromWindowsErr(err);
Steve Dower39294992016-08-30 21:22:36 -0700231 PyEval_SaveThread();
Steve Dower39294992016-08-30 21:22:36 -0700232 }
Steve Dower39294992016-08-30 21:22:36 -0700233 return buf;
234}
235
236#endif
237
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000238
239/* Readline implementation using fgets() */
240
241char *
Serhiy Storchakac6792272013-10-19 21:03:34 +0300242PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000243{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 size_t n;
Christian Heimes9ae513c2013-08-06 15:59:16 +0200245 char *p, *pr;
Victor Stinner6f7346b2020-06-03 18:28:18 +0200246 PyThreadState *tstate = _PyOS_ReadlineTState;
247 assert(tstate != NULL);
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200248
Steve Dower39294992016-08-30 21:22:36 -0700249#ifdef MS_WINDOWS
250 if (!Py_LegacyWindowsStdioFlag && sys_stdin == stdin) {
Steve Dower3cd187b2016-10-08 12:18:16 -0700251 HANDLE hStdIn, hStdErr;
Benjamin Petersone2e792d2016-09-19 22:17:16 -0700252
Steve Dower39294992016-08-30 21:22:36 -0700253 _Py_BEGIN_SUPPRESS_IPH
254 hStdIn = (HANDLE)_get_osfhandle(fileno(sys_stdin));
Steve Dower3cd187b2016-10-08 12:18:16 -0700255 hStdErr = (HANDLE)_get_osfhandle(fileno(stderr));
Steve Dower39294992016-08-30 21:22:36 -0700256 _Py_END_SUPPRESS_IPH
Benjamin Petersone2e792d2016-09-19 22:17:16 -0700257
Steve Dower39294992016-08-30 21:22:36 -0700258 if (_get_console_type(hStdIn) == 'r') {
259 fflush(sys_stdout);
Steve Dower3cd187b2016-10-08 12:18:16 -0700260 if (prompt) {
261 if (_get_console_type(hStdErr) == 'w') {
262 wchar_t *wbuf;
263 int wlen;
264 wlen = MultiByteToWideChar(CP_UTF8, 0, prompt, -1,
265 NULL, 0);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700266 if (wlen) {
267 wbuf = PyMem_RawMalloc(wlen * sizeof(wchar_t));
268 if (wbuf == NULL) {
Victor Stinner6f7346b2020-06-03 18:28:18 +0200269 PyEval_RestoreThread(tstate);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700270 PyErr_NoMemory();
Victor Stinner6f7346b2020-06-03 18:28:18 +0200271 PyEval_SaveThread();
Zackery Spytz4c49da02018-12-07 03:11:30 -0700272 return NULL;
273 }
Steve Dower3cd187b2016-10-08 12:18:16 -0700274 wlen = MultiByteToWideChar(CP_UTF8, 0, prompt, -1,
275 wbuf, wlen);
276 if (wlen) {
277 DWORD n;
278 fflush(stderr);
Steve Dower6c2b9d32016-10-25 11:51:54 -0700279 /* wlen includes null terminator, so subtract 1 */
280 WriteConsoleW(hStdErr, wbuf, wlen - 1, &n, NULL);
Steve Dower3cd187b2016-10-08 12:18:16 -0700281 }
282 PyMem_RawFree(wbuf);
283 }
284 } else {
285 fprintf(stderr, "%s", prompt);
286 fflush(stderr);
287 }
288 }
Steve Dower39294992016-08-30 21:22:36 -0700289 clearerr(sys_stdin);
Victor Stinner6f7346b2020-06-03 18:28:18 +0200290 return _PyOS_WindowsConsoleReadline(tstate, hStdIn);
Steve Dower39294992016-08-30 21:22:36 -0700291 }
292 }
293#endif
294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 n = 100;
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200296 p = (char *)PyMem_RawMalloc(n);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700297 if (p == NULL) {
Victor Stinner6f7346b2020-06-03 18:28:18 +0200298 PyEval_RestoreThread(tstate);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700299 PyErr_NoMemory();
Victor Stinner6f7346b2020-06-03 18:28:18 +0200300 PyEval_SaveThread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 return NULL;
Zackery Spytz4c49da02018-12-07 03:11:30 -0700302 }
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 fflush(sys_stdout);
Victor Stinner6f7346b2020-06-03 18:28:18 +0200305 if (prompt) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 fprintf(stderr, "%s", prompt);
Victor Stinner6f7346b2020-06-03 18:28:18 +0200307 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 fflush(stderr);
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200309
Victor Stinner6f7346b2020-06-03 18:28:18 +0200310 switch (my_fgets(tstate, p, (int)n, sys_stdin)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 case 0: /* Normal case */
312 break;
313 case 1: /* Interrupt */
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200314 PyMem_RawFree(p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 return NULL;
316 case -1: /* EOF */
317 case -2: /* Error */
318 default: /* Shouldn't happen */
319 *p = '\0';
320 break;
321 }
Victor Stinner6f7346b2020-06-03 18:28:18 +0200322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 n = strlen(p);
324 while (n > 0 && p[n-1] != '\n') {
325 size_t incr = n+2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 if (incr > INT_MAX) {
Victor Stinnerc5486602013-10-19 02:40:16 +0200327 PyMem_RawFree(p);
Victor Stinner6f7346b2020-06-03 18:28:18 +0200328 PyEval_RestoreThread(tstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 PyErr_SetString(PyExc_OverflowError, "input line too long");
Victor Stinner6f7346b2020-06-03 18:28:18 +0200330 PyEval_SaveThread();
Christian Heimes9ae513c2013-08-06 15:59:16 +0200331 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 }
Victor Stinner6f7346b2020-06-03 18:28:18 +0200333
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200334 pr = (char *)PyMem_RawRealloc(p, n + incr);
Christian Heimes9ae513c2013-08-06 15:59:16 +0200335 if (pr == NULL) {
Victor Stinnerc5486602013-10-19 02:40:16 +0200336 PyMem_RawFree(p);
Victor Stinner6f7346b2020-06-03 18:28:18 +0200337 PyEval_RestoreThread(tstate);
Christian Heimes9ae513c2013-08-06 15:59:16 +0200338 PyErr_NoMemory();
Victor Stinner6f7346b2020-06-03 18:28:18 +0200339 PyEval_SaveThread();
Christian Heimes9ae513c2013-08-06 15:59:16 +0200340 return NULL;
341 }
342 p = pr;
Victor Stinner6f7346b2020-06-03 18:28:18 +0200343
344 if (my_fgets(tstate, p+n, (int)incr, sys_stdin) != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 break;
Victor Stinner6f7346b2020-06-03 18:28:18 +0200346 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 n += strlen(p+n);
348 }
Victor Stinner6f7346b2020-06-03 18:28:18 +0200349
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200350 pr = (char *)PyMem_RawRealloc(p, n+1);
Christian Heimes9ae513c2013-08-06 15:59:16 +0200351 if (pr == NULL) {
Victor Stinnerc5486602013-10-19 02:40:16 +0200352 PyMem_RawFree(p);
Victor Stinner6f7346b2020-06-03 18:28:18 +0200353 PyEval_RestoreThread(tstate);
Christian Heimes9ae513c2013-08-06 15:59:16 +0200354 PyErr_NoMemory();
Victor Stinner6f7346b2020-06-03 18:28:18 +0200355 PyEval_SaveThread();
Christian Heimes9ae513c2013-08-06 15:59:16 +0200356 return NULL;
357 }
358 return pr;
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000359}
360
361
362/* By initializing this function pointer, systems embedding Python can
Guido van Rossumb18618d2000-05-03 23:44:39 +0000363 override the readline function.
364
365 Note: Python expects in return a buffer allocated with PyMem_Malloc. */
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000366
Benjamin Peterson0a37a302017-12-31 10:04:13 -0800367char *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *) = NULL;
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000368
369
370/* Interface used by tokenizer.c and bltinmodule.c */
371
372char *
Serhiy Storchakac6792272013-10-19 21:03:34 +0300373PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000374{
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200375 char *rv, *res;
376 size_t len;
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000377
Victor Stinner6f7346b2020-06-03 18:28:18 +0200378 PyThreadState *tstate = _PyThreadState_GET();
379 if (_PyOS_ReadlineTState == tstate) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 PyErr_SetString(PyExc_RuntimeError,
381 "can't re-enter readline");
382 return NULL;
383 }
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385
386 if (PyOS_ReadlineFunctionPointer == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000387 PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 }
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390 if (_PyOS_ReadlineLock == NULL) {
391 _PyOS_ReadlineLock = PyThread_allocate_lock();
Zackery Spytz4c49da02018-12-07 03:11:30 -0700392 if (_PyOS_ReadlineLock == NULL) {
393 PyErr_SetString(PyExc_MemoryError, "can't allocate lock");
394 return NULL;
395 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 }
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000397
Victor Stinner6f7346b2020-06-03 18:28:18 +0200398 _PyOS_ReadlineTState = tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 /* This is needed to handle the unlikely case that the
403 * interpreter is in interactive mode *and* stdin/out are not
404 * a tty. This can happen, for example if python is run like
405 * this: python -i < test1.py
406 */
407 if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))
408 rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);
409 else
410 rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
411 prompt);
412 Py_END_ALLOW_THREADS
413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 PyThread_release_lock(_PyOS_ReadlineLock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415
416 _PyOS_ReadlineTState = NULL;
417
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200418 if (rv == NULL)
419 return NULL;
420
421 len = strlen(rv) + 1;
422 res = PyMem_Malloc(len);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700423 if (res != NULL) {
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200424 memcpy(res, rv, len);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700425 }
426 else {
427 PyErr_NoMemory();
428 }
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200429 PyMem_RawFree(rv);
430
431 return res;
Guido van Rossum6fa63431993-12-24 10:36:57 +0000432}