[2] | 1 |
|
---|
| 2 | /* 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.
|
---|
| 6 | 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 |
|
---|
| 12 | #include "Python.h"
|
---|
| 13 | #ifdef MS_WINDOWS
|
---|
| 14 | #define WIN32_LEAN_AND_MEAN
|
---|
| 15 | #include "windows.h"
|
---|
| 16 | #endif /* MS_WINDOWS */
|
---|
| 17 |
|
---|
| 18 | #ifdef __VMS
|
---|
| 19 | extern char* vms__StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt);
|
---|
| 20 | #endif
|
---|
| 21 |
|
---|
| 22 |
|
---|
| 23 | PyThreadState* _PyOS_ReadlineTState;
|
---|
| 24 |
|
---|
| 25 | #ifdef WITH_THREAD
|
---|
| 26 | #include "pythread.h"
|
---|
| 27 | static PyThread_type_lock _PyOS_ReadlineLock = NULL;
|
---|
| 28 | #endif
|
---|
| 29 |
|
---|
| 30 | int (*PyOS_InputHook)(void) = NULL;
|
---|
| 31 |
|
---|
| 32 | #ifdef RISCOS
|
---|
| 33 | int Py_RISCOSWimpFlag;
|
---|
| 34 | #endif
|
---|
| 35 |
|
---|
| 36 | /* This function restarts a fgets() after an EINTR error occurred
|
---|
| 37 | except if PyOS_InterruptOccurred() returns true. */
|
---|
| 38 |
|
---|
| 39 | static int
|
---|
| 40 | my_fgets(char *buf, int len, FILE *fp)
|
---|
| 41 | {
|
---|
[391] | 42 | char *p;
|
---|
[2] | 43 | #ifdef MS_WINDOWS
|
---|
[391] | 44 | int i;
|
---|
| 45 | #endif
|
---|
| 46 |
|
---|
| 47 | while (1) {
|
---|
| 48 | if (PyOS_InputHook != NULL)
|
---|
| 49 | (void)(PyOS_InputHook)();
|
---|
| 50 | errno = 0;
|
---|
| 51 | clearerr(fp);
|
---|
| 52 | p = fgets(buf, len, fp);
|
---|
| 53 | if (p != NULL)
|
---|
| 54 | return 0; /* No error */
|
---|
| 55 | #ifdef MS_WINDOWS
|
---|
| 56 | /* 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. This signal fires in another thread and is not
|
---|
| 60 | guaranteed to have occurred before this point in the code.
|
---|
| 61 |
|
---|
| 62 | Therefore: check in a small loop to see if the trigger has
|
---|
| 63 | fired, in which case assume this is a Ctrl-C event. If it
|
---|
| 64 | hasn't fired within 10ms assume that this is a Ctrl-Z on its
|
---|
| 65 | own or that the signal isn't going to fire for some other
|
---|
| 66 | reason and drop through to check for EOF.
|
---|
| 67 | */
|
---|
| 68 | if (GetLastError()==ERROR_OPERATION_ABORTED) {
|
---|
| 69 | for (i = 0; i < 10; i++) {
|
---|
| 70 | if (PyOS_InterruptOccurred())
|
---|
| 71 | return 1;
|
---|
| 72 | Sleep(1);
|
---|
| 73 | }
|
---|
| 74 | }
|
---|
[2] | 75 | #endif /* MS_WINDOWS */
|
---|
[391] | 76 | if (feof(fp)) {
|
---|
| 77 | clearerr(fp);
|
---|
| 78 | return -1; /* EOF */
|
---|
| 79 | }
|
---|
[2] | 80 | #ifdef EINTR
|
---|
[391] | 81 | if (errno == EINTR) {
|
---|
| 82 | int s;
|
---|
[2] | 83 | #ifdef WITH_THREAD
|
---|
[391] | 84 | PyEval_RestoreThread(_PyOS_ReadlineTState);
|
---|
[2] | 85 | #endif
|
---|
[391] | 86 | s = PyErr_CheckSignals();
|
---|
[2] | 87 | #ifdef WITH_THREAD
|
---|
[391] | 88 | PyEval_SaveThread();
|
---|
[2] | 89 | #endif
|
---|
[391] | 90 | if (s < 0)
|
---|
| 91 | return 1;
|
---|
| 92 | /* try again */
|
---|
| 93 | continue;
|
---|
| 94 | }
|
---|
[2] | 95 | #endif
|
---|
[391] | 96 | if (PyOS_InterruptOccurred()) {
|
---|
| 97 | return 1; /* Interrupt */
|
---|
| 98 | }
|
---|
| 99 | return -2; /* Error */
|
---|
| 100 | }
|
---|
| 101 | /* NOTREACHED */
|
---|
[2] | 102 | }
|
---|
| 103 |
|
---|
| 104 |
|
---|
| 105 | /* Readline implementation using fgets() */
|
---|
| 106 |
|
---|
| 107 | char *
|
---|
| 108 | PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
|
---|
| 109 | {
|
---|
[391] | 110 | size_t n;
|
---|
| 111 | char *p;
|
---|
| 112 | n = 100;
|
---|
| 113 | if ((p = (char *)PyMem_MALLOC(n)) == NULL)
|
---|
| 114 | return NULL;
|
---|
| 115 | fflush(sys_stdout);
|
---|
[2] | 116 | #ifndef RISCOS
|
---|
[391] | 117 | if (prompt)
|
---|
| 118 | fprintf(stderr, "%s", prompt);
|
---|
[2] | 119 | #else
|
---|
[391] | 120 | if (prompt) {
|
---|
| 121 | if(Py_RISCOSWimpFlag)
|
---|
| 122 | fprintf(stderr, "\x0cr%s\x0c", prompt);
|
---|
| 123 | else
|
---|
| 124 | fprintf(stderr, "%s", prompt);
|
---|
| 125 | }
|
---|
[2] | 126 | #endif
|
---|
[391] | 127 | fflush(stderr);
|
---|
| 128 | switch (my_fgets(p, (int)n, sys_stdin)) {
|
---|
| 129 | case 0: /* Normal case */
|
---|
| 130 | break;
|
---|
| 131 | case 1: /* Interrupt */
|
---|
| 132 | PyMem_FREE(p);
|
---|
| 133 | return NULL;
|
---|
| 134 | case -1: /* EOF */
|
---|
| 135 | case -2: /* Error */
|
---|
| 136 | default: /* Shouldn't happen */
|
---|
| 137 | *p = '\0';
|
---|
| 138 | break;
|
---|
| 139 | }
|
---|
| 140 | n = strlen(p);
|
---|
| 141 | while (n > 0 && p[n-1] != '\n') {
|
---|
| 142 | size_t incr = n+2;
|
---|
| 143 | p = (char *)PyMem_REALLOC(p, n + incr);
|
---|
| 144 | if (p == NULL)
|
---|
| 145 | return NULL;
|
---|
| 146 | if (incr > INT_MAX) {
|
---|
| 147 | PyErr_SetString(PyExc_OverflowError, "input line too long");
|
---|
| 148 | }
|
---|
| 149 | if (my_fgets(p+n, (int)incr, sys_stdin) != 0)
|
---|
| 150 | break;
|
---|
| 151 | n += strlen(p+n);
|
---|
| 152 | }
|
---|
| 153 | return (char *)PyMem_REALLOC(p, n+1);
|
---|
[2] | 154 | }
|
---|
| 155 |
|
---|
| 156 |
|
---|
| 157 | /* By initializing this function pointer, systems embedding Python can
|
---|
| 158 | override the readline function.
|
---|
| 159 |
|
---|
| 160 | Note: Python expects in return a buffer allocated with PyMem_Malloc. */
|
---|
| 161 |
|
---|
| 162 | char *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, char *);
|
---|
| 163 |
|
---|
| 164 |
|
---|
| 165 | /* Interface used by tokenizer.c and bltinmodule.c */
|
---|
| 166 |
|
---|
| 167 | char *
|
---|
| 168 | PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
|
---|
| 169 | {
|
---|
[391] | 170 | char *rv;
|
---|
[2] | 171 |
|
---|
[391] | 172 | if (_PyOS_ReadlineTState == PyThreadState_GET()) {
|
---|
| 173 | PyErr_SetString(PyExc_RuntimeError,
|
---|
| 174 | "can't re-enter readline");
|
---|
| 175 | return NULL;
|
---|
| 176 | }
|
---|
[2] | 177 |
|
---|
[391] | 178 |
|
---|
| 179 | if (PyOS_ReadlineFunctionPointer == NULL) {
|
---|
[2] | 180 | #ifdef __VMS
|
---|
[391] | 181 | PyOS_ReadlineFunctionPointer = vms__StdioReadline;
|
---|
[2] | 182 | #else
|
---|
[391] | 183 | PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
|
---|
[2] | 184 | #endif
|
---|
[391] | 185 | }
|
---|
| 186 |
|
---|
[2] | 187 | #ifdef WITH_THREAD
|
---|
[391] | 188 | if (_PyOS_ReadlineLock == NULL) {
|
---|
| 189 | _PyOS_ReadlineLock = PyThread_allocate_lock();
|
---|
| 190 | }
|
---|
[2] | 191 | #endif
|
---|
| 192 |
|
---|
[391] | 193 | _PyOS_ReadlineTState = PyThreadState_GET();
|
---|
| 194 | Py_BEGIN_ALLOW_THREADS
|
---|
[2] | 195 | #ifdef WITH_THREAD
|
---|
[391] | 196 | PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
|
---|
[2] | 197 | #endif
|
---|
| 198 |
|
---|
[391] | 199 | /* This is needed to handle the unlikely case that the
|
---|
| 200 | * interpreter is in interactive mode *and* stdin/out are not
|
---|
| 201 | * a tty. This can happen, for example if python is run like
|
---|
| 202 | * this: python -i < test1.py
|
---|
| 203 | */
|
---|
| 204 | if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))
|
---|
| 205 | rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);
|
---|
| 206 | else
|
---|
| 207 | rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
|
---|
| 208 | prompt);
|
---|
| 209 | Py_END_ALLOW_THREADS
|
---|
[2] | 210 |
|
---|
| 211 | #ifdef WITH_THREAD
|
---|
[391] | 212 | PyThread_release_lock(_PyOS_ReadlineLock);
|
---|
[2] | 213 | #endif
|
---|
| 214 |
|
---|
[391] | 215 | _PyOS_ReadlineTState = NULL;
|
---|
[2] | 216 |
|
---|
[391] | 217 | return rv;
|
---|
[2] | 218 | }
|
---|