blob: b7ff20ab0fb1ccf6a986f14b23ae87282b19ba1f [file] [log] [blame]
Guido van Rossum29c1ea51997-08-07 00:11:34 +00001/*********************************************************
2
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003 msvcrtmodule.c
Guido van Rossum29c1ea51997-08-07 00:11:34 +00004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005 A Python interface to the Microsoft Visual C Runtime
6 Library, providing access to those non-portable, but
7 still useful routines.
Guido van Rossum29c1ea51997-08-07 00:11:34 +00008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00009 Only ever compiled with an MS compiler, so no attempt
10 has been made to avoid MS language extensions, etc...
Guido van Rossum29c1ea51997-08-07 00:11:34 +000011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000012 This may only work on NT or 95...
Guido van Rossum407a22d1997-08-13 19:57:53 +000013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000014 Author: Mark Hammond and Guido van Rossum.
15 Maintenance: Guido van Rossum.
Guido van Rossum407a22d1997-08-13 19:57:53 +000016
Guido van Rossum29c1ea51997-08-07 00:11:34 +000017***********************************************************/
Guido van Rossum407a22d1997-08-13 19:57:53 +000018
Guido van Rossum29c1ea51997-08-07 00:11:34 +000019#include "Python.h"
20#include "malloc.h"
Tim Peters5fa0bd62000-12-12 01:58:56 +000021#include <io.h>
22#include <conio.h>
23#include <sys/locking.h>
Martin v. Löwis3dc33d12007-08-31 07:58:36 +000024#include <crtdbg.h>
25#include <windows.h>
Guido van Rossum29c1ea51997-08-07 00:11:34 +000026
Benjamin Peterson4469d0c2008-11-30 22:46:23 +000027#ifdef _MSC_VER
Martin v. Löwis3afc62e2010-02-18 16:27:43 +000028#if _MSC_VER >= 1500 && _MSC_VER < 1600
Benjamin Peterson4469d0c2008-11-30 22:46:23 +000029#include <crtassem.h>
Brian Curtin401f9f32012-05-13 11:19:23 -050030#elif _MSC_VER >= 1600
31#include <crtversion.h>
Benjamin Peterson4469d0c2008-11-30 22:46:23 +000032#endif
33#endif
34
Zachary Ware45520892015-05-13 01:22:32 -050035/*[python input]
Segev Finer679b5662017-07-27 01:17:57 +030036class HANDLE_converter(CConverter):
37 type = 'void *'
Segev Finera80e9852017-07-27 06:15:18 +030038 format_unit = '"_Py_PARSE_UINTPTR"'
Guido van Rossum407a22d1997-08-13 19:57:53 +000039
Segev Finer679b5662017-07-27 01:17:57 +030040class HANDLE_return_converter(CReturnConverter):
41 type = 'void *'
42
43 def render(self, function, data):
44 self.declare(data)
45 self.err_occurred_if(
46 "_return_value == NULL || _return_value == INVALID_HANDLE_VALUE",
47 data)
48 data.return_conversion.append(
49 'return_value = PyLong_FromVoidPtr(_return_value);\n')
Zachary Ware45520892015-05-13 01:22:32 -050050
51class byte_char_return_converter(CReturnConverter):
52 type = 'int'
53
54 def render(self, function, data):
55 data.declarations.append('char s[1];')
56 data.return_value = 's[0]'
57 data.return_conversion.append(
58 'return_value = PyBytes_FromStringAndSize(s, 1);\n')
59
60class wchar_t_return_converter(CReturnConverter):
61 type = 'wchar_t'
62
63 def render(self, function, data):
64 self.declare(data)
65 data.return_conversion.append(
66 'return_value = PyUnicode_FromOrdinal(_return_value);\n')
67[python start generated code]*/
Segev Finera80e9852017-07-27 06:15:18 +030068/*[python end generated code: output=da39a3ee5e6b4b0d input=d102511df3cda2eb]*/
Zachary Ware45520892015-05-13 01:22:32 -050069
70/*[clinic input]
71module msvcrt
72[clinic start generated code]*/
73/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f31a87a783d036cd]*/
74
75#include "clinic/msvcrtmodule.c.h"
76
77/*[clinic input]
78msvcrt.heapmin
79
80Minimize the malloc() heap.
81
82Force the malloc() heap to clean itself up and return unused blocks
83to the operating system. On failure, this raises OSError.
84[clinic start generated code]*/
85
86static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030087msvcrt_heapmin_impl(PyObject *module)
88/*[clinic end generated code: output=1ba00f344782dc19 input=82e1771d21bde2d8]*/
Zachary Ware45520892015-05-13 01:22:32 -050089{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 if (_heapmin() != 0)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +030091 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum407a22d1997-08-13 19:57:53 +000092
Zachary Ware45520892015-05-13 01:22:32 -050093 Py_RETURN_NONE;
Guido van Rossum29c1ea51997-08-07 00:11:34 +000094}
Zachary Ware45520892015-05-13 01:22:32 -050095/*[clinic input]
96msvcrt.locking
Guido van Rossum29c1ea51997-08-07 00:11:34 +000097
Zachary Ware45520892015-05-13 01:22:32 -050098 fd: int
99 mode: int
100 nbytes: long
101 /
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000102
Zachary Ware45520892015-05-13 01:22:32 -0500103Lock part of a file based on file descriptor fd from the C runtime.
104
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300105Raises OSError on failure. The locked region of the file extends from
Zachary Ware45520892015-05-13 01:22:32 -0500106the current file position for nbytes bytes, and may continue beyond
107the end of the file. mode must be one of the LK_* constants listed
108below. Multiple regions in a file may be locked at the same time, but
109may not overlap. Adjacent regions are not merged; they must be unlocked
110individually.
111[clinic start generated code]*/
112
Tim Peters5fa0bd62000-12-12 01:58:56 +0000113static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300114msvcrt_locking_impl(PyObject *module, int fd, int mode, long nbytes)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300115/*[clinic end generated code: output=a4a90deca9785a03 input=e97bd15fc4a04fef]*/
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000116{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 int err;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000118
Saiyang Gou7514f4f2020-02-12 23:47:42 -0800119 if (PySys_Audit("msvcrt.locking", "iil", fd, mode, nbytes) < 0) {
120 return NULL;
121 }
122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 Py_BEGIN_ALLOW_THREADS
Steve Dower21fae032017-02-04 15:05:13 -0800124 _Py_BEGIN_SUPPRESS_IPH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 err = _locking(fd, mode, nbytes);
Steve Dower21fae032017-02-04 15:05:13 -0800126 _Py_END_SUPPRESS_IPH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 Py_END_ALLOW_THREADS
128 if (err != 0)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300129 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000130
Zachary Ware45520892015-05-13 01:22:32 -0500131 Py_RETURN_NONE;
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000132}
Guido van Rossum407a22d1997-08-13 19:57:53 +0000133
Zachary Ware45520892015-05-13 01:22:32 -0500134/*[clinic input]
135msvcrt.setmode -> long
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000136
Zachary Ware45520892015-05-13 01:22:32 -0500137 fd: int
138 mode as flags: int
139 /
140
141Set the line-end translation mode for the file descriptor fd.
142
143To set it to text mode, flags should be os.O_TEXT; for binary, it
144should be os.O_BINARY.
145
146Return value is the previous mode.
147[clinic start generated code]*/
148
149static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300150msvcrt_setmode_impl(PyObject *module, int fd, int flags)
151/*[clinic end generated code: output=24a9be5ea07ccb9b input=76e7c01f6b137f75]*/
Guido van Rossum407a22d1997-08-13 19:57:53 +0000152{
Steve Dower21fae032017-02-04 15:05:13 -0800153 _Py_BEGIN_SUPPRESS_IPH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 flags = _setmode(fd, flags);
Steve Dower21fae032017-02-04 15:05:13 -0800155 _Py_END_SUPPRESS_IPH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000156 if (flags == -1)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300157 PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000158
Zachary Ware45520892015-05-13 01:22:32 -0500159 return flags;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000160}
161
Zachary Ware45520892015-05-13 01:22:32 -0500162/*[clinic input]
163msvcrt.open_osfhandle -> long
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000164
Segev Finer679b5662017-07-27 01:17:57 +0300165 handle: HANDLE
Zachary Ware45520892015-05-13 01:22:32 -0500166 flags: int
167 /
168
169Create a C runtime file descriptor from the file handle handle.
170
171The flags parameter should be a bitwise OR of os.O_APPEND, os.O_RDONLY,
172and os.O_TEXT. The returned file descriptor may be used as a parameter
173to os.fdopen() to create a file object.
174[clinic start generated code]*/
175
176static long
Segev Finer679b5662017-07-27 01:17:57 +0300177msvcrt_open_osfhandle_impl(PyObject *module, void *handle, int flags)
178/*[clinic end generated code: output=b2fb97c4b515e4e6 input=d5db190a307cf4bb]*/
Guido van Rossum407a22d1997-08-13 19:57:53 +0000179{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 int fd;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000181
Saiyang Gou7514f4f2020-02-12 23:47:42 -0800182 if (PySys_Audit("msvcrt.open_osfhandle", "Ki", handle, flags) < 0) {
Steve Dower6c444d02020-02-20 22:24:44 +0000183 return -1;
Saiyang Gou7514f4f2020-02-12 23:47:42 -0800184 }
185
Steve Dower21fae032017-02-04 15:05:13 -0800186 _Py_BEGIN_SUPPRESS_IPH
Segev Finer679b5662017-07-27 01:17:57 +0300187 fd = _open_osfhandle((intptr_t)handle, flags);
Steve Dower21fae032017-02-04 15:05:13 -0800188 _Py_END_SUPPRESS_IPH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 if (fd == -1)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300190 PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000191
Zachary Ware45520892015-05-13 01:22:32 -0500192 return fd;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000193}
194
Zachary Ware45520892015-05-13 01:22:32 -0500195/*[clinic input]
Segev Finer679b5662017-07-27 01:17:57 +0300196msvcrt.get_osfhandle -> HANDLE
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000197
Zachary Ware45520892015-05-13 01:22:32 -0500198 fd: int
199 /
200
201Return the file handle for the file descriptor fd.
202
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300203Raises OSError if fd is not recognized.
Zachary Ware45520892015-05-13 01:22:32 -0500204[clinic start generated code]*/
205
Segev Finer679b5662017-07-27 01:17:57 +0300206static void *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300207msvcrt_get_osfhandle_impl(PyObject *module, int fd)
Segev Finer679b5662017-07-27 01:17:57 +0300208/*[clinic end generated code: output=aca01dfe24637374 input=5fcfde9b17136aa2]*/
Guido van Rossum407a22d1997-08-13 19:57:53 +0000209{
Benjamin Petersonca470632016-09-06 13:47:26 -0700210 intptr_t handle = -1;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000211
Saiyang Gou7514f4f2020-02-12 23:47:42 -0800212 if (PySys_Audit("msvcrt.get_osfhandle", "(i)", fd) < 0) {
213 return NULL;
214 }
215
Steve Dower8fc89802015-04-12 00:26:27 -0400216 _Py_BEGIN_SUPPRESS_IPH
Steve Dower940f33a2016-09-08 11:21:54 -0700217 handle = _get_osfhandle(fd);
Steve Dower8fc89802015-04-12 00:26:27 -0400218 _Py_END_SUPPRESS_IPH
Steve Dower940f33a2016-09-08 11:21:54 -0700219 if (handle == -1)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300220 PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000221
Segev Finer679b5662017-07-27 01:17:57 +0300222 return (HANDLE)handle;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000223}
224
225/* Console I/O */
Zachary Ware45520892015-05-13 01:22:32 -0500226/*[clinic input]
227msvcrt.kbhit -> long
Guido van Rossum407a22d1997-08-13 19:57:53 +0000228
Zachary Ware45520892015-05-13 01:22:32 -0500229Return true if a keypress is waiting to be read.
230[clinic start generated code]*/
231
232static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300233msvcrt_kbhit_impl(PyObject *module)
234/*[clinic end generated code: output=940dfce6587c1890 input=e70d678a5c2f6acc]*/
Guido van Rossum407a22d1997-08-13 19:57:53 +0000235{
Zachary Ware45520892015-05-13 01:22:32 -0500236 return _kbhit();
Guido van Rossum407a22d1997-08-13 19:57:53 +0000237}
238
Zachary Ware45520892015-05-13 01:22:32 -0500239/*[clinic input]
240msvcrt.getch -> byte_char
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000241
Zachary Ware45520892015-05-13 01:22:32 -0500242Read a keypress and return the resulting character as a byte string.
243
244Nothing is echoed to the console. This call will block if a keypress is
245not already available, but will not wait for Enter to be pressed. If the
246pressed key was a special function key, this will return '\000' or
247'\xe0'; the next call will return the keycode. The Control-C keypress
248cannot be read with this function.
249[clinic start generated code]*/
250
251static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300252msvcrt_getch_impl(PyObject *module)
253/*[clinic end generated code: output=a4e51f0565064a7d input=37a40cf0ed0d1153]*/
Guido van Rossum407a22d1997-08-13 19:57:53 +0000254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255 int ch;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 Py_BEGIN_ALLOW_THREADS
258 ch = _getch();
259 Py_END_ALLOW_THREADS
Zachary Ware45520892015-05-13 01:22:32 -0500260 return ch;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000261}
262
Zachary Ware45520892015-05-13 01:22:32 -0500263/*[clinic input]
264msvcrt.getwch -> wchar_t
265
266Wide char variant of getch(), returning a Unicode value.
267[clinic start generated code]*/
268
269static wchar_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300270msvcrt_getwch_impl(PyObject *module)
271/*[clinic end generated code: output=be9937494e22f007 input=27b3dec8ad823d7c]*/
Christian Heimes2f1019e2007-12-10 16:18:49 +0000272{
Victor Stinner9d3b93b2011-11-22 02:27:30 +0100273 wchar_t ch;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 Py_BEGIN_ALLOW_THREADS
276 ch = _getwch();
277 Py_END_ALLOW_THREADS
Zachary Ware45520892015-05-13 01:22:32 -0500278 return ch;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000279}
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000280
Zachary Ware45520892015-05-13 01:22:32 -0500281/*[clinic input]
282msvcrt.getche -> byte_char
Christian Heimes2f1019e2007-12-10 16:18:49 +0000283
Zachary Ware45520892015-05-13 01:22:32 -0500284Similar to getch(), but the keypress will be echoed if possible.
285[clinic start generated code]*/
286
287static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300288msvcrt_getche_impl(PyObject *module)
289/*[clinic end generated code: output=d8f7db4fd2990401 input=43311ade9ed4a9c0]*/
Guido van Rossum407a22d1997-08-13 19:57:53 +0000290{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 int ch;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293 Py_BEGIN_ALLOW_THREADS
294 ch = _getche();
295 Py_END_ALLOW_THREADS
Zachary Ware45520892015-05-13 01:22:32 -0500296 return ch;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000297}
298
Zachary Ware45520892015-05-13 01:22:32 -0500299/*[clinic input]
300msvcrt.getwche -> wchar_t
301
302Wide char variant of getche(), returning a Unicode value.
303[clinic start generated code]*/
304
305static wchar_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300306msvcrt_getwche_impl(PyObject *module)
307/*[clinic end generated code: output=d0dae5ba3829d596 input=49337d59d1a591f8]*/
Christian Heimes2f1019e2007-12-10 16:18:49 +0000308{
Victor Stinner9d3b93b2011-11-22 02:27:30 +0100309 wchar_t ch;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 Py_BEGIN_ALLOW_THREADS
312 ch = _getwche();
313 Py_END_ALLOW_THREADS
Zachary Ware45520892015-05-13 01:22:32 -0500314 return ch;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000315}
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000316
Zachary Ware45520892015-05-13 01:22:32 -0500317/*[clinic input]
318msvcrt.putch
319
320 char: char
321 /
322
323Print the byte string char to the console without buffering.
324[clinic start generated code]*/
Christian Heimes2f1019e2007-12-10 16:18:49 +0000325
326static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300327msvcrt_putch_impl(PyObject *module, char char_value)
328/*[clinic end generated code: output=92ec9b81012d8f60 input=ec078dd10cb054d6]*/
Guido van Rossum407a22d1997-08-13 19:57:53 +0000329{
Steve Dower21fae032017-02-04 15:05:13 -0800330 _Py_BEGIN_SUPPRESS_IPH
Zachary Ware45520892015-05-13 01:22:32 -0500331 _putch(char_value);
Steve Dower21fae032017-02-04 15:05:13 -0800332 _Py_END_SUPPRESS_IPH
Zachary Ware45520892015-05-13 01:22:32 -0500333 Py_RETURN_NONE;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000334}
335
Zachary Ware45520892015-05-13 01:22:32 -0500336/*[clinic input]
337msvcrt.putwch
338
Zachary Ware77772c02015-05-13 10:58:35 -0500339 unicode_char: int(accept={str})
Zachary Ware45520892015-05-13 01:22:32 -0500340 /
341
342Wide char variant of putch(), accepting a Unicode value.
343[clinic start generated code]*/
344
Christian Heimes2f1019e2007-12-10 16:18:49 +0000345static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300346msvcrt_putwch_impl(PyObject *module, int unicode_char)
347/*[clinic end generated code: output=a3bd1a8951d28eee input=996ccd0bbcbac4c3]*/
Christian Heimes2f1019e2007-12-10 16:18:49 +0000348{
Steve Dower21fae032017-02-04 15:05:13 -0800349 _Py_BEGIN_SUPPRESS_IPH
Zachary Ware45520892015-05-13 01:22:32 -0500350 _putwch(unicode_char);
Steve Dower21fae032017-02-04 15:05:13 -0800351 _Py_END_SUPPRESS_IPH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 Py_RETURN_NONE;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000353
354}
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000355
Zachary Ware45520892015-05-13 01:22:32 -0500356/*[clinic input]
357msvcrt.ungetch
358
359 char: char
360 /
361
362Opposite of getch.
363
364Cause the byte string char to be "pushed back" into the
365console buffer; it will be the next character read by
366getch() or getche().
367[clinic start generated code]*/
Christian Heimes2f1019e2007-12-10 16:18:49 +0000368
Tim Peters5fa0bd62000-12-12 01:58:56 +0000369static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300370msvcrt_ungetch_impl(PyObject *module, char char_value)
371/*[clinic end generated code: output=c6942a0efa119000 input=22f07ee9001bbf0f]*/
Guido van Rossum407a22d1997-08-13 19:57:53 +0000372{
Steve Dower21fae032017-02-04 15:05:13 -0800373 int res;
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +0300374
Steve Dower21fae032017-02-04 15:05:13 -0800375 _Py_BEGIN_SUPPRESS_IPH
376 res = _ungetch(char_value);
377 _Py_END_SUPPRESS_IPH
378
379 if (res == EOF)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300380 return PyErr_SetFromErrno(PyExc_OSError);
Zachary Ware45520892015-05-13 01:22:32 -0500381 Py_RETURN_NONE;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000382}
383
Zachary Ware45520892015-05-13 01:22:32 -0500384/*[clinic input]
385msvcrt.ungetwch
386
Zachary Ware77772c02015-05-13 10:58:35 -0500387 unicode_char: int(accept={str})
Zachary Ware45520892015-05-13 01:22:32 -0500388 /
389
390Wide char variant of ungetch(), accepting a Unicode value.
391[clinic start generated code]*/
392
Christian Heimes2f1019e2007-12-10 16:18:49 +0000393static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300394msvcrt_ungetwch_impl(PyObject *module, int unicode_char)
395/*[clinic end generated code: output=e63af05438b8ba3d input=83ec0492be04d564]*/
Christian Heimes2f1019e2007-12-10 16:18:49 +0000396{
Steve Dower21fae032017-02-04 15:05:13 -0800397 int res;
398
399 _Py_BEGIN_SUPPRESS_IPH
400 res = _ungetwch(unicode_char);
401 _Py_END_SUPPRESS_IPH
402
403 if (res == WEOF)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300404 return PyErr_SetFromErrno(PyExc_OSError);
Zachary Ware45520892015-05-13 01:22:32 -0500405 Py_RETURN_NONE;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000406}
Tim Peters5fa0bd62000-12-12 01:58:56 +0000407
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000408#ifdef _DEBUG
Zachary Ware45520892015-05-13 01:22:32 -0500409/*[clinic input]
Segev Finer679b5662017-07-27 01:17:57 +0300410msvcrt.CrtSetReportFile -> HANDLE
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000411
Zachary Ware45520892015-05-13 01:22:32 -0500412 type: int
Segev Finer679b5662017-07-27 01:17:57 +0300413 file: HANDLE
Zachary Ware45520892015-05-13 01:22:32 -0500414 /
415
416Wrapper around _CrtSetReportFile.
417
418Only available on Debug builds.
419[clinic start generated code]*/
420
Segev Finer679b5662017-07-27 01:17:57 +0300421static void *
422msvcrt_CrtSetReportFile_impl(PyObject *module, int type, void *file)
423/*[clinic end generated code: output=9393e8c77088bbe9 input=290809b5f19e65b9]*/
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000424{
Segev Finer679b5662017-07-27 01:17:57 +0300425 HANDLE res;
Steve Dower21fae032017-02-04 15:05:13 -0800426
427 _Py_BEGIN_SUPPRESS_IPH
Segev Finer679b5662017-07-27 01:17:57 +0300428 res = _CrtSetReportFile(type, file);
Steve Dower21fae032017-02-04 15:05:13 -0800429 _Py_END_SUPPRESS_IPH
430
431 return res;
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000432}
433
Zachary Ware45520892015-05-13 01:22:32 -0500434/*[clinic input]
435msvcrt.CrtSetReportMode -> long
436
437 type: int
438 mode: int
439 /
440
441Wrapper around _CrtSetReportMode.
442
443Only available on Debug builds.
444[clinic start generated code]*/
445
446static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300447msvcrt_CrtSetReportMode_impl(PyObject *module, int type, int mode)
448/*[clinic end generated code: output=b2863761523de317 input=9319d29b4319426b]*/
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000449{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 int res;
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000451
Steve Dower21fae032017-02-04 15:05:13 -0800452 _Py_BEGIN_SUPPRESS_IPH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 res = _CrtSetReportMode(type, mode);
Steve Dower21fae032017-02-04 15:05:13 -0800454 _Py_END_SUPPRESS_IPH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 if (res == -1)
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300456 PyErr_SetFromErrno(PyExc_OSError);
Zachary Ware45520892015-05-13 01:22:32 -0500457 return res;
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000458}
459
Zachary Ware45520892015-05-13 01:22:32 -0500460/*[clinic input]
461msvcrt.set_error_mode -> long
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000462
Zachary Ware45520892015-05-13 01:22:32 -0500463 mode: int
464 /
465
466Wrapper around _set_error_mode.
467
468Only available on Debug builds.
469[clinic start generated code]*/
470
471static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300472msvcrt_set_error_mode_impl(PyObject *module, int mode)
473/*[clinic end generated code: output=ac4a09040d8ac4e3 input=046fca59c0f20872]*/
Zachary Ware45520892015-05-13 01:22:32 -0500474{
Steve Dower21fae032017-02-04 15:05:13 -0800475 long res;
476
477 _Py_BEGIN_SUPPRESS_IPH
478 res = _set_error_mode(mode);
479 _Py_END_SUPPRESS_IPH
480
481 return res;
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000482}
Zachary Ware45520892015-05-13 01:22:32 -0500483#endif /* _DEBUG */
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000484
Zachary Ware45520892015-05-13 01:22:32 -0500485/*[clinic input]
Victor Stinnerf6e58ae2020-06-10 18:49:23 +0200486msvcrt.GetErrorMode
487
488Wrapper around GetErrorMode.
489[clinic start generated code]*/
490
491static PyObject *
492msvcrt_GetErrorMode_impl(PyObject *module)
493/*[clinic end generated code: output=3103fc6145913591 input=5a7fb083b6dd71fd]*/
494{
495 unsigned int res;
496
497 _Py_BEGIN_SUPPRESS_IPH
498 res = GetErrorMode();
499 _Py_END_SUPPRESS_IPH
500
501 return PyLong_FromUnsignedLong(res);
502}
503
504/*[clinic input]
Zachary Ware45520892015-05-13 01:22:32 -0500505msvcrt.SetErrorMode
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000506
Zachary Ware45520892015-05-13 01:22:32 -0500507 mode: unsigned_int(bitwise=True)
508 /
509
510Wrapper around SetErrorMode.
511[clinic start generated code]*/
512
513static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300514msvcrt_SetErrorMode_impl(PyObject *module, unsigned int mode)
515/*[clinic end generated code: output=01d529293f00da8f input=d8b167258d32d907]*/
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000516{
Zachary Ware45520892015-05-13 01:22:32 -0500517 unsigned int res;
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000518
Steve Dower21fae032017-02-04 15:05:13 -0800519 _Py_BEGIN_SUPPRESS_IPH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 res = SetErrorMode(mode);
Steve Dower21fae032017-02-04 15:05:13 -0800521 _Py_END_SUPPRESS_IPH
522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 return PyLong_FromUnsignedLong(res);
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000524}
525
Zachary Ware45520892015-05-13 01:22:32 -0500526/*[clinic input]
527[clinic start generated code]*/
528/*[clinic end generated code: output=da39a3ee5e6b4b0d input=da39a3ee5e6b4b0d]*/
Tim Peters5fa0bd62000-12-12 01:58:56 +0000529
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000530/* List of functions exported by this module */
531static struct PyMethodDef msvcrt_functions[] = {
Zachary Ware45520892015-05-13 01:22:32 -0500532 MSVCRT_HEAPMIN_METHODDEF
533 MSVCRT_LOCKING_METHODDEF
534 MSVCRT_SETMODE_METHODDEF
535 MSVCRT_OPEN_OSFHANDLE_METHODDEF
536 MSVCRT_GET_OSFHANDLE_METHODDEF
537 MSVCRT_KBHIT_METHODDEF
538 MSVCRT_GETCH_METHODDEF
539 MSVCRT_GETCHE_METHODDEF
540 MSVCRT_PUTCH_METHODDEF
541 MSVCRT_UNGETCH_METHODDEF
Victor Stinnerf6e58ae2020-06-10 18:49:23 +0200542 MSVCRT_GETERRORMODE_METHODDEF
Zachary Ware45520892015-05-13 01:22:32 -0500543 MSVCRT_SETERRORMODE_METHODDEF
544 MSVCRT_CRTSETREPORTFILE_METHODDEF
545 MSVCRT_CRTSETREPORTMODE_METHODDEF
546 MSVCRT_SET_ERROR_MODE_METHODDEF
547 MSVCRT_GETWCH_METHODDEF
548 MSVCRT_GETWCHE_METHODDEF
549 MSVCRT_PUTWCH_METHODDEF
550 MSVCRT_UNGETWCH_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 {NULL, NULL}
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000552};
553
Martin v. Löwis1a214512008-06-11 05:26:20 +0000554
555static struct PyModuleDef msvcrtmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 PyModuleDef_HEAD_INIT,
557 "msvcrt",
558 NULL,
559 -1,
560 msvcrt_functions,
561 NULL,
562 NULL,
563 NULL,
564 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000565};
566
Zachary Ware45520892015-05-13 01:22:32 -0500567static void
568insertint(PyObject *d, char *name, int value)
569{
570 PyObject *v = PyLong_FromLong((long) value);
571 if (v == NULL) {
572 /* Don't bother reporting this error */
573 PyErr_Clear();
574 }
575 else {
576 PyDict_SetItemString(d, name, v);
577 Py_DECREF(v);
578 }
579}
580
Segev Finer679b5662017-07-27 01:17:57 +0300581static void
582insertptr(PyObject *d, char *name, void *value)
583{
584 PyObject *v = PyLong_FromVoidPtr(value);
585 if (v == NULL) {
586 /* Don't bother reporting this error */
587 PyErr_Clear();
588 }
589 else {
590 PyDict_SetItemString(d, name, v);
591 Py_DECREF(v);
592 }
593}
594
Thomas Hellera18331d2004-07-28 20:02:52 +0000595PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000596PyInit_msvcrt(void)
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000597{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000598 int st;
Brian Curtin401f9f32012-05-13 11:19:23 -0500599 PyObject *d, *version;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 PyObject *m = PyModule_Create(&msvcrtmodule);
601 if (m == NULL)
602 return NULL;
603 d = PyModule_GetDict(m);
Tim Peters5fa0bd62000-12-12 01:58:56 +0000604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 /* constants for the locking() function's mode argument */
606 insertint(d, "LK_LOCK", _LK_LOCK);
607 insertint(d, "LK_NBLCK", _LK_NBLCK);
608 insertint(d, "LK_NBRLCK", _LK_NBRLCK);
609 insertint(d, "LK_RLCK", _LK_RLCK);
610 insertint(d, "LK_UNLCK", _LK_UNLCK);
611 insertint(d, "SEM_FAILCRITICALERRORS", SEM_FAILCRITICALERRORS);
612 insertint(d, "SEM_NOALIGNMENTFAULTEXCEPT", SEM_NOALIGNMENTFAULTEXCEPT);
613 insertint(d, "SEM_NOGPFAULTERRORBOX", SEM_NOGPFAULTERRORBOX);
614 insertint(d, "SEM_NOOPENFILEERRORBOX", SEM_NOOPENFILEERRORBOX);
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000615#ifdef _DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 insertint(d, "CRT_WARN", _CRT_WARN);
617 insertint(d, "CRT_ERROR", _CRT_ERROR);
618 insertint(d, "CRT_ASSERT", _CRT_ASSERT);
619 insertint(d, "CRTDBG_MODE_DEBUG", _CRTDBG_MODE_DEBUG);
620 insertint(d, "CRTDBG_MODE_FILE", _CRTDBG_MODE_FILE);
621 insertint(d, "CRTDBG_MODE_WNDW", _CRTDBG_MODE_WNDW);
622 insertint(d, "CRTDBG_REPORT_MODE", _CRTDBG_REPORT_MODE);
Segev Finer679b5662017-07-27 01:17:57 +0300623 insertptr(d, "CRTDBG_FILE_STDERR", _CRTDBG_FILE_STDERR);
624 insertptr(d, "CRTDBG_FILE_STDOUT", _CRTDBG_FILE_STDOUT);
625 insertptr(d, "CRTDBG_REPORT_FILE", _CRTDBG_REPORT_FILE);
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000626#endif
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 /* constants for the crt versions */
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000629#ifdef _VC_ASSEMBLY_PUBLICKEYTOKEN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 st = PyModule_AddStringConstant(m, "VC_ASSEMBLY_PUBLICKEYTOKEN",
631 _VC_ASSEMBLY_PUBLICKEYTOKEN);
632 if (st < 0) return NULL;
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000633#endif
634#ifdef _CRT_ASSEMBLY_VERSION
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 st = PyModule_AddStringConstant(m, "CRT_ASSEMBLY_VERSION",
636 _CRT_ASSEMBLY_VERSION);
637 if (st < 0) return NULL;
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000638#endif
639#ifdef __LIBRARIES_ASSEMBLY_NAME_PREFIX
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 st = PyModule_AddStringConstant(m, "LIBRARIES_ASSEMBLY_NAME_PREFIX",
641 __LIBRARIES_ASSEMBLY_NAME_PREFIX);
642 if (st < 0) return NULL;
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000643#endif
644
Brian Curtin401f9f32012-05-13 11:19:23 -0500645 /* constants for the 2010 crt versions */
646#if defined(_VC_CRT_MAJOR_VERSION) && defined (_VC_CRT_MINOR_VERSION) && defined(_VC_CRT_BUILD_VERSION) && defined(_VC_CRT_RBUILD_VERSION)
647 version = PyUnicode_FromFormat("%d.%d.%d.%d", _VC_CRT_MAJOR_VERSION,
648 _VC_CRT_MINOR_VERSION,
649 _VC_CRT_BUILD_VERSION,
650 _VC_CRT_RBUILD_VERSION);
651 st = PyModule_AddObject(m, "CRT_ASSEMBLY_VERSION", version);
652 if (st < 0) return NULL;
653#endif
Victor Stinnerba452952015-09-21 22:40:28 +0200654 /* make compiler warning quiet if st is unused */
655 (void)st;
Brian Curtin401f9f32012-05-13 11:19:23 -0500656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000657 return m;
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000658}