blob: 8b27045f1d643cf6d480aa86f1d8b7804d3f5222 [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
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000018#ifdef __VMS
19extern char* vms__StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt);
20#endif
21
Michael W. Hudson30ea2f22004-07-07 17:44:12 +000022
23PyThreadState* _PyOS_ReadlineTState;
24
Tim Petersb7e898a2004-07-07 20:42:07 +000025#ifdef WITH_THREAD
Michael W. Hudson30ea2f22004-07-07 17:44:12 +000026#include "pythread.h"
27static PyThread_type_lock _PyOS_ReadlineLock = NULL;
28#endif
29
Thomas Wouters23c9e002000-07-22 19:20:54 +000030int (*PyOS_InputHook)(void) = NULL;
Guido van Rossumfbd64c81997-02-18 21:53:32 +000031
32/* This function restarts a fgets() after an EINTR error occurred
33 except if PyOS_InterruptOccurred() returns true. */
34
35static int
Thomas Wouters23c9e002000-07-22 19:20:54 +000036my_fgets(char *buf, int len, FILE *fp)
Guido van Rossumfbd64c81997-02-18 21:53:32 +000037{
Tim Golden9175c3d2012-06-29 18:39:26 +010038#ifdef MS_WINDOWS
39 HANDLE hInterruptEvent;
40#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000041 char *p;
Antoine Pitrouc345ce12011-12-16 12:28:32 +010042 int err;
Victor Stinner52c950f2011-04-09 15:55:44 +020043 while (1) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000044 if (PyOS_InputHook != NULL)
45 (void)(PyOS_InputHook)();
46 errno = 0;
Victor Stinner4f711012011-05-30 23:46:00 +020047 clearerr(fp);
Martin v. Löwise654c112012-04-30 06:10:41 +020048 if (_PyVerify_fd(fileno(fp)))
49 p = fgets(buf, len, fp);
50 else
51 p = NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000052 if (p != NULL)
53 return 0; /* No error */
Antoine Pitrouc345ce12011-12-16 12:28:32 +010054 err = errno;
Mark Hammond2f10cb82002-07-14 23:12:29 +000055#ifdef MS_WINDOWS
Tim Golden9175c3d2012-06-29 18:39:26 +010056 /* Ctrl-C anywhere on the line or Ctrl-Z if the only character
57 on a line will set ERROR_OPERATION_ABORTED. Under normal
58 circumstances Ctrl-C will also have caused the SIGINT handler
59 to fire which will have set the event object returned by
60 _PyOS_SigintEvent. This signal fires in another thread and
61 is not guaranteed to have occurred before this point in the
62 code.
63
64 Therefore: check whether the event is set with a small timeout.
65 If it is, assume this is a Ctrl-C and reset the event. If it
66 isn't set assume that this is a Ctrl-Z on its own and drop
67 through to check for EOF.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068 */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000069 if (GetLastError()==ERROR_OPERATION_ABORTED) {
Tim Golden9175c3d2012-06-29 18:39:26 +010070 hInterruptEvent = _PyOS_SigintEvent();
Martin v. Löwisb26a9b12013-01-25 14:25:48 +010071 switch (WaitForSingleObjectEx(hInterruptEvent, 10, FALSE)) {
Tim Golden9175c3d2012-06-29 18:39:26 +010072 case WAIT_OBJECT_0:
73 ResetEvent(hInterruptEvent);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000074 return 1; /* Interrupt */
Tim Golden9175c3d2012-06-29 18:39:26 +010075 case WAIT_FAILED:
76 return -2; /* Error */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000077 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000078 }
Mark Hammond2f10cb82002-07-14 23:12:29 +000079#endif /* MS_WINDOWS */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000080 if (feof(fp)) {
Victor Stinner4755ab02011-05-10 00:19:53 +020081 clearerr(fp);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000082 return -1; /* EOF */
83 }
Guido van Rossumfbd64c81997-02-18 21:53:32 +000084#ifdef EINTR
Antoine Pitrouc345ce12011-12-16 12:28:32 +010085 if (err == EINTR) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000086 int s;
Michael W. Hudsone3afc592005-04-07 10:11:19 +000087#ifdef WITH_THREAD
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000088 PyEval_RestoreThread(_PyOS_ReadlineTState);
Michael W. Hudsone3afc592005-04-07 10:11:19 +000089#endif
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000090 s = PyErr_CheckSignals();
Michael W. Hudsone3afc592005-04-07 10:11:19 +000091#ifdef WITH_THREAD
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000092 PyEval_SaveThread();
Michael W. Hudsone3afc592005-04-07 10:11:19 +000093#endif
Victor Stinner52c950f2011-04-09 15:55:44 +020094 if (s < 0)
95 return 1;
Tim Golden9175c3d2012-06-29 18:39:26 +010096 /* try again */
Victor Stinner52c950f2011-04-09 15:55:44 +020097 continue;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000098 }
Guido van Rossumfbd64c81997-02-18 21:53:32 +000099#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100 if (PyOS_InterruptOccurred()) {
101 return 1; /* Interrupt */
102 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000103 return -2; /* Error */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000105 /* NOTREACHED */
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000106}
107
108
109/* Readline implementation using fgets() */
110
111char *
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000112PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000113{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114 size_t n;
115 char *p;
116 n = 100;
117 if ((p = (char *)PyMem_MALLOC(n)) == NULL)
118 return NULL;
119 fflush(sys_stdout);
120 if (prompt)
121 fprintf(stderr, "%s", prompt);
122 fflush(stderr);
123 switch (my_fgets(p, (int)n, sys_stdin)) {
124 case 0: /* Normal case */
125 break;
126 case 1: /* Interrupt */
127 PyMem_FREE(p);
128 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;
138 p = (char *)PyMem_REALLOC(p, n + incr);
139 if (p == NULL)
140 return NULL;
141 if (incr > INT_MAX) {
142 PyErr_SetString(PyExc_OverflowError, "input line too long");
143 }
144 if (my_fgets(p+n, (int)incr, sys_stdin) != 0)
145 break;
146 n += strlen(p+n);
147 }
148 return (char *)PyMem_REALLOC(p, n+1);
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000149}
150
151
152/* By initializing this function pointer, systems embedding Python can
Guido van Rossumb18618d2000-05-03 23:44:39 +0000153 override the readline function.
154
155 Note: Python expects in return a buffer allocated with PyMem_Malloc. */
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000156
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000157char *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, char *);
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000158
159
160/* Interface used by tokenizer.c and bltinmodule.c */
161
162char *
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000163PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 char *rv;
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 if (_PyOS_ReadlineTState == PyThreadState_GET()) {
168 PyErr_SetString(PyExc_RuntimeError,
169 "can't re-enter readline");
170 return NULL;
171 }
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173
174 if (PyOS_ReadlineFunctionPointer == NULL) {
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000175#ifdef __VMS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 PyOS_ReadlineFunctionPointer = vms__StdioReadline;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000177#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000178 PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000179#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 }
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000181
Tim Petersb7e898a2004-07-07 20:42:07 +0000182#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000183 if (_PyOS_ReadlineLock == NULL) {
184 _PyOS_ReadlineLock = PyThread_allocate_lock();
185 }
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000186#endif
187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 _PyOS_ReadlineTState = PyThreadState_GET();
189 Py_BEGIN_ALLOW_THREADS
190#ifdef WITH_THREAD
191 PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
192#endif
Michael W. Hudson30ea2f22004-07-07 17:44:12 +0000193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 /* This is needed to handle the unlikely case that the
195 * interpreter is in interactive mode *and* stdin/out are not
196 * a tty. This can happen, for example if python is run like
197 * this: python -i < test1.py
198 */
199 if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))
200 rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);
201 else
202 rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
203 prompt);
204 Py_END_ALLOW_THREADS
205
206#ifdef WITH_THREAD
207 PyThread_release_lock(_PyOS_ReadlineLock);
208#endif
209
210 _PyOS_ReadlineTState = NULL;
211
212 return rv;
Guido van Rossum6fa63431993-12-24 10:36:57 +0000213}