17db96d56Sopenharmony_ci/* Testing module for multi-phase initialization of extension modules (PEP 489) 27db96d56Sopenharmony_ci */ 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ci#ifndef Py_BUILD_CORE_BUILTIN 57db96d56Sopenharmony_ci# define Py_BUILD_CORE_MODULE 1 67db96d56Sopenharmony_ci#endif 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci#include "Python.h" 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ci#ifdef MS_WINDOWS 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ci#include "pycore_fileutils.h" // _Py_get_osfhandle() 137db96d56Sopenharmony_ci#include "..\modules\_io\_iomodule.h" 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ci#define WIN32_LEAN_AND_MEAN 167db96d56Sopenharmony_ci#include <windows.h> 177db96d56Sopenharmony_ci#include <fcntl.h> 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ci /* The full definition is in iomodule. We reproduce 207db96d56Sopenharmony_ci enough here to get the fd, which is all we want. */ 217db96d56Sopenharmony_citypedef struct { 227db96d56Sopenharmony_ci PyObject_HEAD 237db96d56Sopenharmony_ci int fd; 247db96d56Sopenharmony_ci} winconsoleio; 257db96d56Sopenharmony_ci 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_cistatic int execfunc(PyObject *m) 287db96d56Sopenharmony_ci{ 297db96d56Sopenharmony_ci return 0; 307db96d56Sopenharmony_ci} 317db96d56Sopenharmony_ci 327db96d56Sopenharmony_ciPyModuleDef_Slot testconsole_slots[] = { 337db96d56Sopenharmony_ci {Py_mod_exec, execfunc}, 347db96d56Sopenharmony_ci {0, NULL}, 357db96d56Sopenharmony_ci}; 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_ci/*[clinic input] 387db96d56Sopenharmony_cimodule _testconsole 397db96d56Sopenharmony_ci 407db96d56Sopenharmony_ci_testconsole.write_input 417db96d56Sopenharmony_ci file: object 427db96d56Sopenharmony_ci s: PyBytesObject 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ciWrites UTF-16-LE encoded bytes to the console as if typed by a user. 457db96d56Sopenharmony_ci[clinic start generated code]*/ 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_cistatic PyObject * 487db96d56Sopenharmony_ci_testconsole_write_input_impl(PyObject *module, PyObject *file, 497db96d56Sopenharmony_ci PyBytesObject *s) 507db96d56Sopenharmony_ci/*[clinic end generated code: output=48f9563db34aedb3 input=4c774f2d05770bc6]*/ 517db96d56Sopenharmony_ci{ 527db96d56Sopenharmony_ci INPUT_RECORD *rec = NULL; 537db96d56Sopenharmony_ci 547db96d56Sopenharmony_ci if (!PyWindowsConsoleIO_Check(file)) { 557db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "expected raw console object"); 567db96d56Sopenharmony_ci return NULL; 577db96d56Sopenharmony_ci } 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_ci const wchar_t *p = (const wchar_t *)PyBytes_AS_STRING(s); 607db96d56Sopenharmony_ci DWORD size = (DWORD)PyBytes_GET_SIZE(s) / sizeof(wchar_t); 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci rec = (INPUT_RECORD*)PyMem_Calloc(size, sizeof(INPUT_RECORD)); 637db96d56Sopenharmony_ci if (!rec) 647db96d56Sopenharmony_ci goto error; 657db96d56Sopenharmony_ci 667db96d56Sopenharmony_ci INPUT_RECORD *prec = rec; 677db96d56Sopenharmony_ci for (DWORD i = 0; i < size; ++i, ++p, ++prec) { 687db96d56Sopenharmony_ci prec->EventType = KEY_EVENT; 697db96d56Sopenharmony_ci prec->Event.KeyEvent.bKeyDown = TRUE; 707db96d56Sopenharmony_ci prec->Event.KeyEvent.wRepeatCount = 1; 717db96d56Sopenharmony_ci prec->Event.KeyEvent.uChar.UnicodeChar = *p; 727db96d56Sopenharmony_ci } 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_ci HANDLE hInput = _Py_get_osfhandle(((winconsoleio*)file)->fd); 757db96d56Sopenharmony_ci if (hInput == INVALID_HANDLE_VALUE) 767db96d56Sopenharmony_ci goto error; 777db96d56Sopenharmony_ci 787db96d56Sopenharmony_ci DWORD total = 0; 797db96d56Sopenharmony_ci while (total < size) { 807db96d56Sopenharmony_ci DWORD wrote; 817db96d56Sopenharmony_ci if (!WriteConsoleInputW(hInput, &rec[total], (size - total), &wrote)) { 827db96d56Sopenharmony_ci PyErr_SetFromWindowsErr(0); 837db96d56Sopenharmony_ci goto error; 847db96d56Sopenharmony_ci } 857db96d56Sopenharmony_ci total += wrote; 867db96d56Sopenharmony_ci } 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_ci PyMem_Free((void*)rec); 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ci Py_RETURN_NONE; 917db96d56Sopenharmony_cierror: 927db96d56Sopenharmony_ci if (rec) 937db96d56Sopenharmony_ci PyMem_Free((void*)rec); 947db96d56Sopenharmony_ci return NULL; 957db96d56Sopenharmony_ci} 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci/*[clinic input] 987db96d56Sopenharmony_ci_testconsole.read_output 997db96d56Sopenharmony_ci file: object 1007db96d56Sopenharmony_ci 1017db96d56Sopenharmony_ciReads a str from the console as written to stdout. 1027db96d56Sopenharmony_ci[clinic start generated code]*/ 1037db96d56Sopenharmony_ci 1047db96d56Sopenharmony_cistatic PyObject * 1057db96d56Sopenharmony_ci_testconsole_read_output_impl(PyObject *module, PyObject *file) 1067db96d56Sopenharmony_ci/*[clinic end generated code: output=876310d81a73e6d2 input=b3521f64b1b558e3]*/ 1077db96d56Sopenharmony_ci{ 1087db96d56Sopenharmony_ci Py_RETURN_NONE; 1097db96d56Sopenharmony_ci} 1107db96d56Sopenharmony_ci 1117db96d56Sopenharmony_ci#include "clinic\_testconsole.c.h" 1127db96d56Sopenharmony_ci 1137db96d56Sopenharmony_ciPyMethodDef testconsole_methods[] = { 1147db96d56Sopenharmony_ci _TESTCONSOLE_WRITE_INPUT_METHODDEF 1157db96d56Sopenharmony_ci _TESTCONSOLE_READ_OUTPUT_METHODDEF 1167db96d56Sopenharmony_ci {NULL, NULL} 1177db96d56Sopenharmony_ci}; 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_cistatic PyModuleDef testconsole_def = { 1207db96d56Sopenharmony_ci PyModuleDef_HEAD_INIT, /* m_base */ 1217db96d56Sopenharmony_ci "_testconsole", /* m_name */ 1227db96d56Sopenharmony_ci PyDoc_STR("Test module for the Windows console"), /* m_doc */ 1237db96d56Sopenharmony_ci 0, /* m_size */ 1247db96d56Sopenharmony_ci testconsole_methods, /* m_methods */ 1257db96d56Sopenharmony_ci testconsole_slots, /* m_slots */ 1267db96d56Sopenharmony_ci NULL, /* m_traverse */ 1277db96d56Sopenharmony_ci NULL, /* m_clear */ 1287db96d56Sopenharmony_ci NULL, /* m_free */ 1297db96d56Sopenharmony_ci}; 1307db96d56Sopenharmony_ci 1317db96d56Sopenharmony_ciPyMODINIT_FUNC 1327db96d56Sopenharmony_ciPyInit__testconsole(PyObject *spec) 1337db96d56Sopenharmony_ci{ 1347db96d56Sopenharmony_ci return PyModuleDef_Init(&testconsole_def); 1357db96d56Sopenharmony_ci} 1367db96d56Sopenharmony_ci 1377db96d56Sopenharmony_ci#endif /* MS_WINDOWS */ 138