blob: 04c2793225cb3d9f0e1df34e7a0105c7830afd7f [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 Stinnere5014be2020-04-14 17:52:15 +020013#include "pycore_pystate.h" // _PyThreadState_GET()
Mark Hammond2f10cb82002-07-14 23:12:29 +000014#ifdef MS_WINDOWS
Victor Stinnere5014be2020-04-14 17:52:15 +020015# define WIN32_LEAN_AND_MEAN
16# include "windows.h"
Mark Hammond2f10cb82002-07-14 23:12:29 +000017#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 +000022static PyThread_type_lock _PyOS_ReadlineLock = NULL;
Michael W. Hudson30ea2f22004-07-07 17:44:12 +000023
Thomas Wouters23c9e002000-07-22 19:20:54 +000024int (*PyOS_InputHook)(void) = NULL;
Guido van Rossumfbd64c81997-02-18 21:53:32 +000025
26/* This function restarts a fgets() after an EINTR error occurred
27 except if PyOS_InterruptOccurred() returns true. */
28
29static int
Thomas Wouters23c9e002000-07-22 19:20:54 +000030my_fgets(char *buf, int len, FILE *fp)
Guido van Rossumfbd64c81997-02-18 21:53:32 +000031{
Tim Golden9175c3d2012-06-29 18:39:26 +010032#ifdef MS_WINDOWS
33 HANDLE hInterruptEvent;
34#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000035 char *p;
Antoine Pitrouc345ce12011-12-16 12:28:32 +010036 int err;
Victor Stinner52c950f2011-04-09 15:55:44 +020037 while (1) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000038 if (PyOS_InputHook != NULL)
39 (void)(PyOS_InputHook)();
40 errno = 0;
Victor Stinner4f711012011-05-30 23:46:00 +020041 clearerr(fp);
Steve Dower940f33a2016-09-08 11:21:54 -070042 p = fgets(buf, len, fp);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000043 if (p != NULL)
44 return 0; /* No error */
Antoine Pitrouc345ce12011-12-16 12:28:32 +010045 err = errno;
Mark Hammond2f10cb82002-07-14 23:12:29 +000046#ifdef MS_WINDOWS
Tim Golden9175c3d2012-06-29 18:39:26 +010047 /* Ctrl-C anywhere on the line or Ctrl-Z if the only character
48 on a line will set ERROR_OPERATION_ABORTED. Under normal
49 circumstances Ctrl-C will also have caused the SIGINT handler
50 to fire which will have set the event object returned by
51 _PyOS_SigintEvent. This signal fires in another thread and
52 is not guaranteed to have occurred before this point in the
53 code.
54
55 Therefore: check whether the event is set with a small timeout.
56 If it is, assume this is a Ctrl-C and reset the event. If it
57 isn't set assume that this is a Ctrl-Z on its own and drop
58 through to check for EOF.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000059 */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000060 if (GetLastError()==ERROR_OPERATION_ABORTED) {
Tim Golden9175c3d2012-06-29 18:39:26 +010061 hInterruptEvent = _PyOS_SigintEvent();
Martin v. Löwisb26a9b12013-01-25 14:25:48 +010062 switch (WaitForSingleObjectEx(hInterruptEvent, 10, FALSE)) {
Tim Golden9175c3d2012-06-29 18:39:26 +010063 case WAIT_OBJECT_0:
64 ResetEvent(hInterruptEvent);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000065 return 1; /* Interrupt */
Tim Golden9175c3d2012-06-29 18:39:26 +010066 case WAIT_FAILED:
67 return -2; /* Error */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000068 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000069 }
Mark Hammond2f10cb82002-07-14 23:12:29 +000070#endif /* MS_WINDOWS */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000071 if (feof(fp)) {
Victor Stinner4755ab02011-05-10 00:19:53 +020072 clearerr(fp);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000073 return -1; /* EOF */
74 }
Guido van Rossumfbd64c81997-02-18 21:53:32 +000075#ifdef EINTR
Antoine Pitrouc345ce12011-12-16 12:28:32 +010076 if (err == EINTR) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000077 int s;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000078 PyEval_RestoreThread(_PyOS_ReadlineTState);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000079 s = PyErr_CheckSignals();
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000080 PyEval_SaveThread();
Victor Stinner52c950f2011-04-09 15:55:44 +020081 if (s < 0)
82 return 1;
Tim Golden9175c3d2012-06-29 18:39:26 +010083 /* try again */
Victor Stinner52c950f2011-04-09 15:55:44 +020084 continue;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000085 }
Guido van Rossumfbd64c81997-02-18 21:53:32 +000086#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 if (PyOS_InterruptOccurred()) {
88 return 1; /* Interrupt */
89 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000090 return -2; /* Error */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000092 /* NOTREACHED */
Guido van Rossumfbd64c81997-02-18 21:53:32 +000093}
94
Steve Dower39294992016-08-30 21:22:36 -070095#ifdef MS_WINDOWS
96/* Readline implementation using ReadConsoleW */
97
98extern char _get_console_type(HANDLE handle);
99
100char *
101_PyOS_WindowsConsoleReadline(HANDLE hStdIn)
102{
103 static wchar_t wbuf_local[1024 * 16];
104 const DWORD chunk_size = 1024;
105
106 DWORD n_read, total_read, wbuflen, u8len;
107 wchar_t *wbuf;
108 char *buf = NULL;
109 int err = 0;
110
ValeriyaSinevichce75df32018-07-19 15:34:03 -0700111 n_read = (DWORD)-1;
Steve Dower39294992016-08-30 21:22:36 -0700112 total_read = 0;
113 wbuf = wbuf_local;
114 wbuflen = sizeof(wbuf_local) / sizeof(wbuf_local[0]) - 1;
115 while (1) {
Thomas A Caswell9b9d58f2018-06-28 12:29:44 -0400116 if (PyOS_InputHook != NULL) {
117 (void)(PyOS_InputHook)();
118 }
Steve Dower39294992016-08-30 21:22:36 -0700119 if (!ReadConsoleW(hStdIn, &wbuf[total_read], wbuflen - total_read, &n_read, NULL)) {
120 err = GetLastError();
121 goto exit;
122 }
ValeriyaSinevichce75df32018-07-19 15:34:03 -0700123 if (n_read == (DWORD)-1 && (err = GetLastError()) == ERROR_OPERATION_ABORTED) {
124 break;
125 }
Steve Dower39294992016-08-30 21:22:36 -0700126 if (n_read == 0) {
127 int s;
128 err = GetLastError();
129 if (err != ERROR_OPERATION_ABORTED)
130 goto exit;
131 err = 0;
132 HANDLE hInterruptEvent = _PyOS_SigintEvent();
133 if (WaitForSingleObjectEx(hInterruptEvent, 100, FALSE)
134 == WAIT_OBJECT_0) {
135 ResetEvent(hInterruptEvent);
Steve Dower39294992016-08-30 21:22:36 -0700136 PyEval_RestoreThread(_PyOS_ReadlineTState);
Steve Dower39294992016-08-30 21:22:36 -0700137 s = PyErr_CheckSignals();
Steve Dower39294992016-08-30 21:22:36 -0700138 PyEval_SaveThread();
Steve Dower39294992016-08-30 21:22:36 -0700139 if (s < 0)
140 goto exit;
141 }
142 break;
143 }
144
145 total_read += n_read;
146 if (total_read == 0 || wbuf[total_read - 1] == L'\n') {
147 break;
148 }
149 wbuflen += chunk_size;
150 if (wbuf == wbuf_local) {
151 wbuf[total_read] = '\0';
152 wbuf = (wchar_t*)PyMem_RawMalloc(wbuflen * sizeof(wchar_t));
153 if (wbuf)
154 wcscpy_s(wbuf, wbuflen, wbuf_local);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700155 else {
156 PyErr_NoMemory();
157 goto exit;
158 }
Steve Dower39294992016-08-30 21:22:36 -0700159 }
Zackery Spytz4c49da02018-12-07 03:11:30 -0700160 else {
161 wchar_t *tmp = PyMem_RawRealloc(wbuf, wbuflen * sizeof(wchar_t));
162 if (tmp == NULL) {
163 PyErr_NoMemory();
164 goto exit;
165 }
166 wbuf = tmp;
167 }
Steve Dower39294992016-08-30 21:22:36 -0700168 }
169
170 if (wbuf[0] == '\x1a') {
171 buf = PyMem_RawMalloc(1);
172 if (buf)
173 buf[0] = '\0';
Zackery Spytz4c49da02018-12-07 03:11:30 -0700174 else {
175 PyErr_NoMemory();
176 }
Steve Dower39294992016-08-30 21:22:36 -0700177 goto exit;
178 }
179
180 u8len = WideCharToMultiByte(CP_UTF8, 0, wbuf, total_read, NULL, 0, NULL, NULL);
181 buf = PyMem_RawMalloc(u8len + 1);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700182 if (buf == NULL) {
183 PyErr_NoMemory();
184 goto exit;
185 }
Steve Dower39294992016-08-30 21:22:36 -0700186 u8len = WideCharToMultiByte(CP_UTF8, 0, wbuf, total_read, buf, u8len, NULL, NULL);
187 buf[u8len] = '\0';
Benjamin Petersone2e792d2016-09-19 22:17:16 -0700188
Steve Dower39294992016-08-30 21:22:36 -0700189exit:
190 if (wbuf != wbuf_local)
191 PyMem_RawFree(wbuf);
192
193 if (err) {
Steve Dower39294992016-08-30 21:22:36 -0700194 PyEval_RestoreThread(_PyOS_ReadlineTState);
Steve Dower39294992016-08-30 21:22:36 -0700195 PyErr_SetFromWindowsErr(err);
Steve Dower39294992016-08-30 21:22:36 -0700196 PyEval_SaveThread();
Steve Dower39294992016-08-30 21:22:36 -0700197 }
198
199 return buf;
200}
201
202#endif
203
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000204
205/* Readline implementation using fgets() */
206
207char *
Serhiy Storchakac6792272013-10-19 21:03:34 +0300208PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 size_t n;
Christian Heimes9ae513c2013-08-06 15:59:16 +0200211 char *p, *pr;
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200212
Steve Dower39294992016-08-30 21:22:36 -0700213#ifdef MS_WINDOWS
214 if (!Py_LegacyWindowsStdioFlag && sys_stdin == stdin) {
Steve Dower3cd187b2016-10-08 12:18:16 -0700215 HANDLE hStdIn, hStdErr;
Benjamin Petersone2e792d2016-09-19 22:17:16 -0700216
Steve Dower39294992016-08-30 21:22:36 -0700217 _Py_BEGIN_SUPPRESS_IPH
218 hStdIn = (HANDLE)_get_osfhandle(fileno(sys_stdin));
Steve Dower3cd187b2016-10-08 12:18:16 -0700219 hStdErr = (HANDLE)_get_osfhandle(fileno(stderr));
Steve Dower39294992016-08-30 21:22:36 -0700220 _Py_END_SUPPRESS_IPH
Benjamin Petersone2e792d2016-09-19 22:17:16 -0700221
Steve Dower39294992016-08-30 21:22:36 -0700222 if (_get_console_type(hStdIn) == 'r') {
223 fflush(sys_stdout);
Steve Dower3cd187b2016-10-08 12:18:16 -0700224 if (prompt) {
225 if (_get_console_type(hStdErr) == 'w') {
226 wchar_t *wbuf;
227 int wlen;
228 wlen = MultiByteToWideChar(CP_UTF8, 0, prompt, -1,
229 NULL, 0);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700230 if (wlen) {
231 wbuf = PyMem_RawMalloc(wlen * sizeof(wchar_t));
232 if (wbuf == NULL) {
233 PyErr_NoMemory();
234 return NULL;
235 }
Steve Dower3cd187b2016-10-08 12:18:16 -0700236 wlen = MultiByteToWideChar(CP_UTF8, 0, prompt, -1,
237 wbuf, wlen);
238 if (wlen) {
239 DWORD n;
240 fflush(stderr);
Steve Dower6c2b9d32016-10-25 11:51:54 -0700241 /* wlen includes null terminator, so subtract 1 */
242 WriteConsoleW(hStdErr, wbuf, wlen - 1, &n, NULL);
Steve Dower3cd187b2016-10-08 12:18:16 -0700243 }
244 PyMem_RawFree(wbuf);
245 }
246 } else {
247 fprintf(stderr, "%s", prompt);
248 fflush(stderr);
249 }
250 }
Steve Dower39294992016-08-30 21:22:36 -0700251 clearerr(sys_stdin);
252 return _PyOS_WindowsConsoleReadline(hStdIn);
253 }
254 }
255#endif
256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 n = 100;
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200258 p = (char *)PyMem_RawMalloc(n);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700259 if (p == NULL) {
260 PyErr_NoMemory();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 return NULL;
Zackery Spytz4c49da02018-12-07 03:11:30 -0700262 }
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 fflush(sys_stdout);
265 if (prompt)
266 fprintf(stderr, "%s", prompt);
267 fflush(stderr);
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 switch (my_fgets(p, (int)n, sys_stdin)) {
270 case 0: /* Normal case */
271 break;
272 case 1: /* Interrupt */
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200273 PyMem_RawFree(p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274 return NULL;
275 case -1: /* EOF */
276 case -2: /* Error */
277 default: /* Shouldn't happen */
278 *p = '\0';
279 break;
280 }
281 n = strlen(p);
282 while (n > 0 && p[n-1] != '\n') {
283 size_t incr = n+2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 if (incr > INT_MAX) {
Victor Stinnerc5486602013-10-19 02:40:16 +0200285 PyMem_RawFree(p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 PyErr_SetString(PyExc_OverflowError, "input line too long");
Christian Heimes9ae513c2013-08-06 15:59:16 +0200287 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 }
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200289 pr = (char *)PyMem_RawRealloc(p, n + incr);
Christian Heimes9ae513c2013-08-06 15:59:16 +0200290 if (pr == NULL) {
Victor Stinnerc5486602013-10-19 02:40:16 +0200291 PyMem_RawFree(p);
Christian Heimes9ae513c2013-08-06 15:59:16 +0200292 PyErr_NoMemory();
293 return NULL;
294 }
295 p = pr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 if (my_fgets(p+n, (int)incr, sys_stdin) != 0)
297 break;
298 n += strlen(p+n);
299 }
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200300 pr = (char *)PyMem_RawRealloc(p, n+1);
Christian Heimes9ae513c2013-08-06 15:59:16 +0200301 if (pr == NULL) {
Victor Stinnerc5486602013-10-19 02:40:16 +0200302 PyMem_RawFree(p);
Christian Heimes9ae513c2013-08-06 15:59:16 +0200303 PyErr_NoMemory();
304 return NULL;
305 }
306 return pr;
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000307}
308
309
310/* By initializing this function pointer, systems embedding Python can
Guido van Rossumb18618d2000-05-03 23:44:39 +0000311 override the readline function.
312
313 Note: Python expects in return a buffer allocated with PyMem_Malloc. */
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000314
Benjamin Peterson0a37a302017-12-31 10:04:13 -0800315char *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *) = NULL;
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000316
317
318/* Interface used by tokenizer.c and bltinmodule.c */
319
320char *
Serhiy Storchakac6792272013-10-19 21:03:34 +0300321PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000322{
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200323 char *rv, *res;
324 size_t len;
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000325
Victor Stinner50b48572018-11-01 01:51:40 +0100326 if (_PyOS_ReadlineTState == _PyThreadState_GET()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327 PyErr_SetString(PyExc_RuntimeError,
328 "can't re-enter readline");
329 return NULL;
330 }
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332
333 if (PyOS_ReadlineFunctionPointer == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 }
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 if (_PyOS_ReadlineLock == NULL) {
338 _PyOS_ReadlineLock = PyThread_allocate_lock();
Zackery Spytz4c49da02018-12-07 03:11:30 -0700339 if (_PyOS_ReadlineLock == NULL) {
340 PyErr_SetString(PyExc_MemoryError, "can't allocate lock");
341 return NULL;
342 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 }
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000344
Victor Stinner50b48572018-11-01 01:51:40 +0100345 _PyOS_ReadlineTState = _PyThreadState_GET();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000346 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 /* This is needed to handle the unlikely case that the
350 * interpreter is in interactive mode *and* stdin/out are not
351 * a tty. This can happen, for example if python is run like
352 * this: python -i < test1.py
353 */
354 if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))
355 rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);
356 else
357 rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
358 prompt);
359 Py_END_ALLOW_THREADS
360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 PyThread_release_lock(_PyOS_ReadlineLock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362
363 _PyOS_ReadlineTState = NULL;
364
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200365 if (rv == NULL)
366 return NULL;
367
368 len = strlen(rv) + 1;
369 res = PyMem_Malloc(len);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700370 if (res != NULL) {
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200371 memcpy(res, rv, len);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700372 }
373 else {
374 PyErr_NoMemory();
375 }
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200376 PyMem_RawFree(rv);
377
378 return res;
Guido van Rossum6fa63431993-12-24 10:36:57 +0000379}