myreadline.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. /* Readline interface for tokenizer.c and [raw_]input() in bltinmodule.c.
  2. By default, or when stdin is not a tty device, we have a super
  3. simple my_readline function using fgets.
  4. Optionally, we can use the GNU readline library.
  5. my_readline() has a different return value from GNU readline():
  6. - NULL if an interrupt occurred or if an error occurred
  7. - a malloc'ed empty string if EOF was read
  8. - a malloc'ed string ending in \n normally
  9. */
  10. #include "Python.h"
  11. #include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH
  12. #include "pycore_pystate.h" // _PyThreadState_GET()
  13. #ifdef MS_WINDOWS
  14. # ifndef WIN32_LEAN_AND_MEAN
  15. # define WIN32_LEAN_AND_MEAN
  16. # endif
  17. # include "windows.h"
  18. #endif /* MS_WINDOWS */
  19. PyThreadState* _PyOS_ReadlineTState = NULL;
  20. static PyThread_type_lock _PyOS_ReadlineLock = NULL;
  21. int (*PyOS_InputHook)(void) = NULL;
  22. /* This function restarts a fgets() after an EINTR error occurred
  23. except if _PyOS_InterruptOccurred() returns true. */
  24. static int
  25. my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp)
  26. {
  27. #ifdef MS_WINDOWS
  28. HANDLE handle;
  29. _Py_BEGIN_SUPPRESS_IPH
  30. handle = (HANDLE)_get_osfhandle(fileno(fp));
  31. _Py_END_SUPPRESS_IPH
  32. /* bpo-40826: fgets(fp) does crash if fileno(fp) is closed */
  33. if (handle == INVALID_HANDLE_VALUE) {
  34. return -1; /* EOF */
  35. }
  36. #endif
  37. while (1) {
  38. if (PyOS_InputHook != NULL &&
  39. // GH-104668: See PyOS_ReadlineFunctionPointer's comment below...
  40. _Py_IsMainInterpreter(tstate->interp))
  41. {
  42. (void)(PyOS_InputHook)();
  43. }
  44. errno = 0;
  45. clearerr(fp);
  46. char *p = fgets(buf, len, fp);
  47. if (p != NULL) {
  48. return 0; /* No error */
  49. }
  50. int err = errno;
  51. #ifdef MS_WINDOWS
  52. /* 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. Therefore: check whether the event is set with a small timeout.
  60. If it is, assume this is a Ctrl-C and reset the event. If it
  61. isn't set assume that this is a Ctrl-Z on its own and drop
  62. through to check for EOF.
  63. */
  64. if (GetLastError()==ERROR_OPERATION_ABORTED) {
  65. HANDLE hInterruptEvent = _PyOS_SigintEvent();
  66. switch (WaitForSingleObjectEx(hInterruptEvent, 10, FALSE)) {
  67. case WAIT_OBJECT_0:
  68. ResetEvent(hInterruptEvent);
  69. return 1; /* Interrupt */
  70. case WAIT_FAILED:
  71. return -2; /* Error */
  72. }
  73. }
  74. #endif /* MS_WINDOWS */
  75. if (feof(fp)) {
  76. clearerr(fp);
  77. return -1; /* EOF */
  78. }
  79. #ifdef EINTR
  80. if (err == EINTR) {
  81. PyEval_RestoreThread(tstate);
  82. int s = PyErr_CheckSignals();
  83. PyEval_SaveThread();
  84. if (s < 0) {
  85. return 1;
  86. }
  87. /* try again */
  88. continue;
  89. }
  90. #endif
  91. if (_PyOS_InterruptOccurred(tstate)) {
  92. return 1; /* Interrupt */
  93. }
  94. return -2; /* Error */
  95. }
  96. /* NOTREACHED */
  97. }
  98. #ifdef HAVE_WINDOWS_CONSOLE_IO
  99. /* Readline implementation using ReadConsoleW */
  100. extern char _get_console_type(HANDLE handle);
  101. char *
  102. _PyOS_WindowsConsoleReadline(PyThreadState *tstate, HANDLE hStdIn)
  103. {
  104. static wchar_t wbuf_local[1024 * 16];
  105. const DWORD chunk_size = 1024;
  106. DWORD n_read, total_read, wbuflen, u8len;
  107. wchar_t *wbuf;
  108. char *buf = NULL;
  109. int err = 0;
  110. n_read = (DWORD)-1;
  111. total_read = 0;
  112. wbuf = wbuf_local;
  113. wbuflen = sizeof(wbuf_local) / sizeof(wbuf_local[0]) - 1;
  114. while (1) {
  115. if (PyOS_InputHook != NULL &&
  116. // GH-104668: See PyOS_ReadlineFunctionPointer's comment below...
  117. _Py_IsMainInterpreter(tstate->interp))
  118. {
  119. (void)(PyOS_InputHook)();
  120. }
  121. if (!ReadConsoleW(hStdIn, &wbuf[total_read], wbuflen - total_read, &n_read, NULL)) {
  122. err = GetLastError();
  123. goto exit;
  124. }
  125. if (n_read == (DWORD)-1 && (err = GetLastError()) == ERROR_OPERATION_ABORTED) {
  126. break;
  127. }
  128. if (n_read == 0) {
  129. int s;
  130. err = GetLastError();
  131. if (err != ERROR_OPERATION_ABORTED)
  132. goto exit;
  133. err = 0;
  134. HANDLE hInterruptEvent = _PyOS_SigintEvent();
  135. if (WaitForSingleObjectEx(hInterruptEvent, 100, FALSE)
  136. == WAIT_OBJECT_0) {
  137. ResetEvent(hInterruptEvent);
  138. PyEval_RestoreThread(tstate);
  139. s = PyErr_CheckSignals();
  140. PyEval_SaveThread();
  141. if (s < 0) {
  142. goto exit;
  143. }
  144. }
  145. break;
  146. }
  147. total_read += n_read;
  148. if (total_read == 0 || wbuf[total_read - 1] == L'\n') {
  149. break;
  150. }
  151. wbuflen += chunk_size;
  152. if (wbuf == wbuf_local) {
  153. wbuf[total_read] = '\0';
  154. wbuf = (wchar_t*)PyMem_RawMalloc(wbuflen * sizeof(wchar_t));
  155. if (wbuf) {
  156. wcscpy_s(wbuf, wbuflen, wbuf_local);
  157. }
  158. else {
  159. PyEval_RestoreThread(tstate);
  160. PyErr_NoMemory();
  161. PyEval_SaveThread();
  162. goto exit;
  163. }
  164. }
  165. else {
  166. wchar_t *tmp = PyMem_RawRealloc(wbuf, wbuflen * sizeof(wchar_t));
  167. if (tmp == NULL) {
  168. PyEval_RestoreThread(tstate);
  169. PyErr_NoMemory();
  170. PyEval_SaveThread();
  171. goto exit;
  172. }
  173. wbuf = tmp;
  174. }
  175. }
  176. if (wbuf[0] == '\x1a') {
  177. buf = PyMem_RawMalloc(1);
  178. if (buf) {
  179. buf[0] = '\0';
  180. }
  181. else {
  182. PyEval_RestoreThread(tstate);
  183. PyErr_NoMemory();
  184. PyEval_SaveThread();
  185. }
  186. goto exit;
  187. }
  188. u8len = WideCharToMultiByte(CP_UTF8, 0,
  189. wbuf, total_read,
  190. NULL, 0,
  191. NULL, NULL);
  192. buf = PyMem_RawMalloc(u8len + 1);
  193. if (buf == NULL) {
  194. PyEval_RestoreThread(tstate);
  195. PyErr_NoMemory();
  196. PyEval_SaveThread();
  197. goto exit;
  198. }
  199. u8len = WideCharToMultiByte(CP_UTF8, 0,
  200. wbuf, total_read,
  201. buf, u8len,
  202. NULL, NULL);
  203. buf[u8len] = '\0';
  204. exit:
  205. if (wbuf != wbuf_local) {
  206. PyMem_RawFree(wbuf);
  207. }
  208. if (err) {
  209. PyEval_RestoreThread(tstate);
  210. PyErr_SetFromWindowsErr(err);
  211. PyEval_SaveThread();
  212. }
  213. return buf;
  214. }
  215. #endif /* HAVE_WINDOWS_CONSOLE_IO */
  216. /* Readline implementation using fgets() */
  217. char *
  218. PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
  219. {
  220. size_t n;
  221. char *p, *pr;
  222. PyThreadState *tstate = _PyOS_ReadlineTState;
  223. assert(tstate != NULL);
  224. #ifdef HAVE_WINDOWS_CONSOLE_IO
  225. const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
  226. if (!config->legacy_windows_stdio && sys_stdin == stdin) {
  227. HANDLE hStdIn, hStdErr;
  228. hStdIn = _Py_get_osfhandle_noraise(fileno(sys_stdin));
  229. hStdErr = _Py_get_osfhandle_noraise(fileno(stderr));
  230. if (_get_console_type(hStdIn) == 'r') {
  231. fflush(sys_stdout);
  232. if (prompt) {
  233. if (_get_console_type(hStdErr) == 'w') {
  234. wchar_t *wbuf;
  235. int wlen;
  236. wlen = MultiByteToWideChar(CP_UTF8, 0, prompt, -1,
  237. NULL, 0);
  238. if (wlen) {
  239. wbuf = PyMem_RawMalloc(wlen * sizeof(wchar_t));
  240. if (wbuf == NULL) {
  241. PyEval_RestoreThread(tstate);
  242. PyErr_NoMemory();
  243. PyEval_SaveThread();
  244. return NULL;
  245. }
  246. wlen = MultiByteToWideChar(CP_UTF8, 0, prompt, -1,
  247. wbuf, wlen);
  248. if (wlen) {
  249. DWORD n;
  250. fflush(stderr);
  251. /* wlen includes null terminator, so subtract 1 */
  252. WriteConsoleW(hStdErr, wbuf, wlen - 1, &n, NULL);
  253. }
  254. PyMem_RawFree(wbuf);
  255. }
  256. } else {
  257. fprintf(stderr, "%s", prompt);
  258. fflush(stderr);
  259. }
  260. }
  261. clearerr(sys_stdin);
  262. return _PyOS_WindowsConsoleReadline(tstate, hStdIn);
  263. }
  264. }
  265. #endif
  266. fflush(sys_stdout);
  267. if (prompt) {
  268. fprintf(stderr, "%s", prompt);
  269. }
  270. fflush(stderr);
  271. n = 0;
  272. p = NULL;
  273. do {
  274. size_t incr = (n > 0) ? n + 2 : 100;
  275. if (incr > INT_MAX) {
  276. PyMem_RawFree(p);
  277. PyEval_RestoreThread(tstate);
  278. PyErr_SetString(PyExc_OverflowError, "input line too long");
  279. PyEval_SaveThread();
  280. return NULL;
  281. }
  282. pr = (char *)PyMem_RawRealloc(p, n + incr);
  283. if (pr == NULL) {
  284. PyMem_RawFree(p);
  285. PyEval_RestoreThread(tstate);
  286. PyErr_NoMemory();
  287. PyEval_SaveThread();
  288. return NULL;
  289. }
  290. p = pr;
  291. int err = my_fgets(tstate, p + n, (int)incr, sys_stdin);
  292. if (err == 1) {
  293. // Interrupt
  294. PyMem_RawFree(p);
  295. return NULL;
  296. } else if (err != 0) {
  297. // EOF or error
  298. p[n] = '\0';
  299. break;
  300. }
  301. n += strlen(p + n);
  302. } while (p[n-1] != '\n');
  303. pr = (char *)PyMem_RawRealloc(p, n+1);
  304. if (pr == NULL) {
  305. PyMem_RawFree(p);
  306. PyEval_RestoreThread(tstate);
  307. PyErr_NoMemory();
  308. PyEval_SaveThread();
  309. return NULL;
  310. }
  311. return pr;
  312. }
  313. /* By initializing this function pointer, systems embedding Python can
  314. override the readline function.
  315. Note: Python expects in return a buffer allocated with PyMem_Malloc. */
  316. char *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *) = NULL;
  317. /* Interface used by tokenizer.c and bltinmodule.c */
  318. char *
  319. PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
  320. {
  321. char *rv, *res;
  322. size_t len;
  323. PyThreadState *tstate = _PyThreadState_GET();
  324. if (_PyOS_ReadlineTState == tstate) {
  325. PyErr_SetString(PyExc_RuntimeError,
  326. "can't re-enter readline");
  327. return NULL;
  328. }
  329. if (PyOS_ReadlineFunctionPointer == NULL) {
  330. PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
  331. }
  332. if (_PyOS_ReadlineLock == NULL) {
  333. _PyOS_ReadlineLock = PyThread_allocate_lock();
  334. if (_PyOS_ReadlineLock == NULL) {
  335. PyErr_SetString(PyExc_MemoryError, "can't allocate lock");
  336. return NULL;
  337. }
  338. }
  339. _PyOS_ReadlineTState = tstate;
  340. Py_BEGIN_ALLOW_THREADS
  341. PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
  342. /* This is needed to handle the unlikely case that the
  343. * interpreter is in interactive mode *and* stdin/out are not
  344. * a tty. This can happen, for example if python is run like
  345. * this: python -i < test1.py
  346. */
  347. if (!isatty(fileno(sys_stdin)) || !isatty(fileno(sys_stdout)) ||
  348. // GH-104668: Don't call global callbacks like PyOS_InputHook or
  349. // PyOS_ReadlineFunctionPointer from subinterpreters, since it seems
  350. // like there's no good way for users (like readline and tkinter) to
  351. // avoid using global state to manage them. Plus, we generally don't
  352. // want to cause trouble for libraries that don't know/care about
  353. // subinterpreter support. If libraries really need better APIs that
  354. // work per-interpreter and have ways to access module state, we can
  355. // certainly add them later (but for now we'll cross our fingers and
  356. // hope that nobody actually cares):
  357. !_Py_IsMainInterpreter(tstate->interp))
  358. {
  359. rv = PyOS_StdioReadline(sys_stdin, sys_stdout, prompt);
  360. }
  361. else {
  362. rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout, prompt);
  363. }
  364. Py_END_ALLOW_THREADS
  365. PyThread_release_lock(_PyOS_ReadlineLock);
  366. _PyOS_ReadlineTState = NULL;
  367. if (rv == NULL)
  368. return NULL;
  369. len = strlen(rv) + 1;
  370. res = PyMem_Malloc(len);
  371. if (res != NULL) {
  372. memcpy(res, rv, len);
  373. }
  374. else {
  375. PyErr_NoMemory();
  376. }
  377. PyMem_RawFree(rv);
  378. return res;
  379. }