blob: 28c7b6d7fff83c2c1d0f6421ef8a364abda5fa6f [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"
Mark Hammond2f10cb82002-07-14 23:12:29 +000013#ifdef MS_WINDOWS
14#define WIN32_LEAN_AND_MEAN
15#include "windows.h"
16#endif /* MS_WINDOWS */
Guido van Rossum6fa63431993-12-24 10:36:57 +000017
Michael W. Hudson30ea2f22004-07-07 17:44:12 +000018
19PyThreadState* _PyOS_ReadlineTState;
20
Tim Petersb7e898a2004-07-07 20:42:07 +000021#ifdef WITH_THREAD
Michael W. Hudson30ea2f22004-07-07 17:44:12 +000022#include "pythread.h"
23static PyThread_type_lock _PyOS_ReadlineLock = NULL;
24#endif
25
Thomas Wouters23c9e002000-07-22 19:20:54 +000026int (*PyOS_InputHook)(void) = NULL;
Guido van Rossumfbd64c81997-02-18 21:53:32 +000027
28/* This function restarts a fgets() after an EINTR error occurred
29 except if PyOS_InterruptOccurred() returns true. */
30
31static int
Thomas Wouters23c9e002000-07-22 19:20:54 +000032my_fgets(char *buf, int len, FILE *fp)
Guido van Rossumfbd64c81997-02-18 21:53:32 +000033{
Tim Golden9175c3d2012-06-29 18:39:26 +010034#ifdef MS_WINDOWS
35 HANDLE hInterruptEvent;
36#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037 char *p;
Antoine Pitrouc345ce12011-12-16 12:28:32 +010038 int err;
Victor Stinner52c950f2011-04-09 15:55:44 +020039 while (1) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000040 if (PyOS_InputHook != NULL)
41 (void)(PyOS_InputHook)();
42 errno = 0;
Victor Stinner4f711012011-05-30 23:46:00 +020043 clearerr(fp);
Martin v. Löwise654c112012-04-30 06:10:41 +020044 if (_PyVerify_fd(fileno(fp)))
45 p = fgets(buf, len, fp);
46 else
47 p = NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000048 if (p != NULL)
49 return 0; /* No error */
Antoine Pitrouc345ce12011-12-16 12:28:32 +010050 err = errno;
Mark Hammond2f10cb82002-07-14 23:12:29 +000051#ifdef MS_WINDOWS
Tim Golden9175c3d2012-06-29 18:39:26 +010052 /* Ctrl-C anywhere on the line or Ctrl-Z if the only character
53 on a line will set ERROR_OPERATION_ABORTED. Under normal
54 circumstances Ctrl-C will also have caused the SIGINT handler
55 to fire which will have set the event object returned by
56 _PyOS_SigintEvent. This signal fires in another thread and
57 is not guaranteed to have occurred before this point in the
58 code.
59
60 Therefore: check whether the event is set with a small timeout.
61 If it is, assume this is a Ctrl-C and reset the event. If it
62 isn't set assume that this is a Ctrl-Z on its own and drop
63 through to check for EOF.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064 */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000065 if (GetLastError()==ERROR_OPERATION_ABORTED) {
Tim Golden9175c3d2012-06-29 18:39:26 +010066 hInterruptEvent = _PyOS_SigintEvent();
Martin v. Löwisb26a9b12013-01-25 14:25:48 +010067 switch (WaitForSingleObjectEx(hInterruptEvent, 10, FALSE)) {
Tim Golden9175c3d2012-06-29 18:39:26 +010068 case WAIT_OBJECT_0:
69 ResetEvent(hInterruptEvent);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000070 return 1; /* Interrupt */
Tim Golden9175c3d2012-06-29 18:39:26 +010071 case WAIT_FAILED:
72 return -2; /* Error */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000073 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000074 }
Mark Hammond2f10cb82002-07-14 23:12:29 +000075#endif /* MS_WINDOWS */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000076 if (feof(fp)) {
Victor Stinner4755ab02011-05-10 00:19:53 +020077 clearerr(fp);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000078 return -1; /* EOF */
79 }
Guido van Rossumfbd64c81997-02-18 21:53:32 +000080#ifdef EINTR
Antoine Pitrouc345ce12011-12-16 12:28:32 +010081 if (err == EINTR) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000082 int s;
Michael W. Hudsone3afc592005-04-07 10:11:19 +000083#ifdef WITH_THREAD
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000084 PyEval_RestoreThread(_PyOS_ReadlineTState);
Michael W. Hudsone3afc592005-04-07 10:11:19 +000085#endif
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000086 s = PyErr_CheckSignals();
Michael W. Hudsone3afc592005-04-07 10:11:19 +000087#ifdef WITH_THREAD
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000088 PyEval_SaveThread();
Michael W. Hudsone3afc592005-04-07 10:11:19 +000089#endif
Victor Stinner52c950f2011-04-09 15:55:44 +020090 if (s < 0)
91 return 1;
Tim Golden9175c3d2012-06-29 18:39:26 +010092 /* try again */
Victor Stinner52c950f2011-04-09 15:55:44 +020093 continue;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000094 }
Guido van Rossumfbd64c81997-02-18 21:53:32 +000095#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000096 if (PyOS_InterruptOccurred()) {
97 return 1; /* Interrupt */
98 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000099 return -2; /* Error */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000101 /* NOTREACHED */
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000102}
103
104
105/* Readline implementation using fgets() */
106
107char *
Serhiy Storchakac6792272013-10-19 21:03:34 +0300108PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000109{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110 size_t n;
Christian Heimes9ae513c2013-08-06 15:59:16 +0200111 char *p, *pr;
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 n = 100;
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200114 p = (char *)PyMem_RawMalloc(n);
115 if (p == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 return NULL;
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118 fflush(sys_stdout);
119 if (prompt)
120 fprintf(stderr, "%s", prompt);
121 fflush(stderr);
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 switch (my_fgets(p, (int)n, sys_stdin)) {
124 case 0: /* Normal case */
125 break;
126 case 1: /* Interrupt */
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200127 PyMem_RawFree(p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000128 return NULL;
129 case -1: /* EOF */
130 case -2: /* Error */
131 default: /* Shouldn't happen */
132 *p = '\0';
133 break;
134 }
135 n = strlen(p);
136 while (n > 0 && p[n-1] != '\n') {
137 size_t incr = n+2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000138 if (incr > INT_MAX) {
Victor Stinnerc5486602013-10-19 02:40:16 +0200139 PyMem_RawFree(p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000140 PyErr_SetString(PyExc_OverflowError, "input line too long");
Christian Heimes9ae513c2013-08-06 15:59:16 +0200141 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000142 }
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200143 pr = (char *)PyMem_RawRealloc(p, n + incr);
Christian Heimes9ae513c2013-08-06 15:59:16 +0200144 if (pr == NULL) {
Victor Stinnerc5486602013-10-19 02:40:16 +0200145 PyMem_RawFree(p);
Christian Heimes9ae513c2013-08-06 15:59:16 +0200146 PyErr_NoMemory();
147 return NULL;
148 }
149 p = pr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 if (my_fgets(p+n, (int)incr, sys_stdin) != 0)
151 break;
152 n += strlen(p+n);
153 }
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200154 pr = (char *)PyMem_RawRealloc(p, n+1);
Christian Heimes9ae513c2013-08-06 15:59:16 +0200155 if (pr == NULL) {
Victor Stinnerc5486602013-10-19 02:40:16 +0200156 PyMem_RawFree(p);
Christian Heimes9ae513c2013-08-06 15:59:16 +0200157 PyErr_NoMemory();
158 return NULL;
159 }
160 return pr;
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000161}
162
163
164/* By initializing this function pointer, systems embedding Python can
Guido van Rossumb18618d2000-05-03 23:44:39 +0000165 override the readline function.
166
167 Note: Python expects in return a buffer allocated with PyMem_Malloc. */
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000168
Serhiy Storchakac6792272013-10-19 21:03:34 +0300169char *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *);
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000170
171
172/* Interface used by tokenizer.c and bltinmodule.c */
173
174char *
Serhiy Storchakac6792272013-10-19 21:03:34 +0300175PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000176{
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200177 char *rv, *res;
178 size_t len;
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 if (_PyOS_ReadlineTState == PyThreadState_GET()) {
181 PyErr_SetString(PyExc_RuntimeError,
182 "can't re-enter readline");
183 return NULL;
184 }
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186
187 if (PyOS_ReadlineFunctionPointer == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 }
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000190
Tim Petersb7e898a2004-07-07 20:42:07 +0000191#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 if (_PyOS_ReadlineLock == NULL) {
193 _PyOS_ReadlineLock = PyThread_allocate_lock();
194 }
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000195#endif
196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 _PyOS_ReadlineTState = PyThreadState_GET();
198 Py_BEGIN_ALLOW_THREADS
199#ifdef WITH_THREAD
200 PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
201#endif
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 /* This is needed to handle the unlikely case that the
204 * interpreter is in interactive mode *and* stdin/out are not
205 * a tty. This can happen, for example if python is run like
206 * this: python -i < test1.py
207 */
208 if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))
209 rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);
210 else
211 rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
212 prompt);
213 Py_END_ALLOW_THREADS
214
215#ifdef WITH_THREAD
216 PyThread_release_lock(_PyOS_ReadlineLock);
217#endif
218
219 _PyOS_ReadlineTState = NULL;
220
Victor Stinner2fe9bac2013-10-10 16:18:20 +0200221 if (rv == NULL)
222 return NULL;
223
224 len = strlen(rv) + 1;
225 res = PyMem_Malloc(len);
226 if (res != NULL)
227 memcpy(res, rv, len);
228 PyMem_RawFree(rv);
229
230 return res;
Guido van Rossum6fa63431993-12-24 10:36:57 +0000231}