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 { 42 char *p; 43 #ifdef MS_WINDOWS 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 } 75 #endif /* MS_WINDOWS */ 76 if (feof(fp)) { 77 clearerr(fp); 78 return -1; /* EOF */ 79 } 80 #ifdef EINTR 81 if (errno == EINTR) { 82 int s; 83 #ifdef WITH_THREAD 84 PyEval_RestoreThread(_PyOS_ReadlineTState); 85 #endif 86 s = PyErr_CheckSignals(); 87 #ifdef WITH_THREAD 88 PyEval_SaveThread(); 89 #endif 90 if (s < 0) 91 return 1; 92 /* try again */ 93 continue; 94 } 95 #endif 96 if (PyOS_InterruptOccurred()) { 97 return 1; /* Interrupt */ 98 } 99 return -2; /* Error */ 100 } 101 /* NOTREACHED */ 102 } 103 104 105 /* Readline implementation using fgets() */ 106 107 char * 108 PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt) 109 { 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); 116 #ifndef RISCOS 117 if (prompt) 118 fprintf(stderr, "%s", prompt); 119 #else 120 if (prompt) { 121 if(Py_RISCOSWimpFlag) 122 fprintf(stderr, "\x0cr%s\x0c", prompt); 123 else 124 fprintf(stderr, "%s", prompt); 125 } 126 #endif 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); 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 { 170 char *rv; 171 172 if (_PyOS_ReadlineTState == PyThreadState_GET()) { 173 PyErr_SetString(PyExc_RuntimeError, 174 "can't re-enter readline"); 175 return NULL; 176 } 177 178 179 if (PyOS_ReadlineFunctionPointer == NULL) { 180 #ifdef __VMS 181 PyOS_ReadlineFunctionPointer = vms__StdioReadline; 182 #else 183 PyOS_ReadlineFunctionPointer = PyOS_StdioReadline; 184 #endif 185 } 186 187 #ifdef WITH_THREAD 188 if (_PyOS_ReadlineLock == NULL) { 189 _PyOS_ReadlineLock = PyThread_allocate_lock(); 190 } 191 #endif 192 193 _PyOS_ReadlineTState = PyThreadState_GET(); 194 Py_BEGIN_ALLOW_THREADS 195 #ifdef WITH_THREAD 196 PyThread_acquire_lock(_PyOS_ReadlineLock, 1); 197 #endif 198 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 210 211 #ifdef WITH_THREAD 212 PyThread_release_lock(_PyOS_ReadlineLock); 213 #endif 214 215 _PyOS_ReadlineTState = NULL; 216 217 return rv; 218 } 219