blob: c8345c524efbcdae9763f1aba682d745a25eaa2b [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
Guido van Rossum407a22d1997-08-13 19:57:53 +000035// Force the malloc heap to clean itself up, and free unused blocks
36// back to the OS. (According to the docs, only works on NT.)
Tim Peters5fa0bd62000-12-12 01:58:56 +000037static PyObject *
38msvcrt_heapmin(PyObject *self, PyObject *args)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000039{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000040 if (!PyArg_ParseTuple(args, ":heapmin"))
41 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +000042
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000043 if (_heapmin() != 0)
44 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum407a22d1997-08-13 19:57:53 +000045
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000046 Py_INCREF(Py_None);
47 return Py_None;
Guido van Rossum29c1ea51997-08-07 00:11:34 +000048}
49
Benjamin Peterson1baf4652009-12-31 03:11:23 +000050PyDoc_STRVAR(heapmin_doc,
51"heapmin() -> None\n\
52\n\
53Force the malloc() heap to clean itself up and return unused blocks\n\
54to the operating system. On failure, this raises IOError.");
55
Guido van Rossum407a22d1997-08-13 19:57:53 +000056// Perform locking operations on a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000057static PyObject *
58msvcrt_locking(PyObject *self, PyObject *args)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000059{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 int fd;
61 int mode;
62 long nbytes;
63 int err;
Guido van Rossum407a22d1997-08-13 19:57:53 +000064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000065 if (!PyArg_ParseTuple(args, "iil:locking", &fd, &mode, &nbytes))
66 return NULL;
Guido van Rossum29c1ea51997-08-07 00:11:34 +000067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068 Py_BEGIN_ALLOW_THREADS
69 err = _locking(fd, mode, nbytes);
70 Py_END_ALLOW_THREADS
71 if (err != 0)
72 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum29c1ea51997-08-07 00:11:34 +000073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 Py_INCREF(Py_None);
75 return Py_None;
Guido van Rossum29c1ea51997-08-07 00:11:34 +000076}
Guido van Rossum407a22d1997-08-13 19:57:53 +000077
Benjamin Peterson1baf4652009-12-31 03:11:23 +000078PyDoc_STRVAR(locking_doc,
79"locking(fd, mode, nbytes) -> None\n\
80\n\
81Lock part of a file based on file descriptor fd from the C runtime.\n\
82Raises IOError on failure. The locked region of the file extends from\n\
83the current file position for nbytes bytes, and may continue beyond\n\
84the end of the file. mode must be one of the LK_* constants listed\n\
85below. Multiple regions in a file may be locked at the same time, but\n\
86may not overlap. Adjacent regions are not merged; they must be unlocked\n\
87individually.");
88
Guido van Rossum407a22d1997-08-13 19:57:53 +000089// Set the file translation mode for a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000090static PyObject *
91msvcrt_setmode(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +000092{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 int fd;
94 int flags;
95 if (!PyArg_ParseTuple(args,"ii:setmode", &fd, &flags))
96 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +000097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 flags = _setmode(fd, flags);
99 if (flags == -1)
100 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000102 return PyLong_FromLong(flags);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000103}
104
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000105PyDoc_STRVAR(setmode_doc,
106"setmode(fd, mode) -> Previous mode\n\
107\n\
108Set the line-end translation mode for the file descriptor fd. To set\n\
109it to text mode, flags should be os.O_TEXT; for binary, it should be\n\
110os.O_BINARY.");
111
Guido van Rossum407a22d1997-08-13 19:57:53 +0000112// Convert an OS file handle to a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +0000113static PyObject *
114msvcrt_open_osfhandle(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000115{
Richard Oudkerkac0ad882013-06-05 23:29:30 +0100116 Py_intptr_t handle;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 int flags;
118 int fd;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000119
Richard Oudkerkac0ad882013-06-05 23:29:30 +0100120 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:open_osfhandle",
121 &handle, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000122 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 fd = _open_osfhandle(handle, flags);
125 if (fd == -1)
126 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000128 return PyLong_FromLong(fd);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000129}
130
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000131PyDoc_STRVAR(open_osfhandle_doc,
132"open_osfhandle(handle, flags) -> file descriptor\n\
133\n\
134Create a C runtime file descriptor from the file handle handle. The\n\
135flags parameter should be a bitwise OR of os.O_APPEND, os.O_RDONLY,\n\
136and os.O_TEXT. The returned file descriptor may be used as a parameter\n\
137to os.fdopen() to create a file object.");
138
Guido van Rossum407a22d1997-08-13 19:57:53 +0000139// Convert a C runtime file descriptor to an OS file handle.
Tim Peters5fa0bd62000-12-12 01:58:56 +0000140static PyObject *
141msvcrt_get_osfhandle(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000142{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000143 int fd;
144 Py_intptr_t handle;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000146 if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd))
147 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000148
Antoine Pitrou00492492010-09-04 20:53:29 +0000149 if (!_PyVerify_fd(fd))
150 return PyErr_SetFromErrno(PyExc_IOError);
151
Steve Dower8fc89802015-04-12 00:26:27 -0400152 _Py_BEGIN_SUPPRESS_IPH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 handle = _get_osfhandle(fd);
Steve Dower8fc89802015-04-12 00:26:27 -0400154 _Py_END_SUPPRESS_IPH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 if (handle == -1)
156 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 /* technically 'handle' is not a pointer, but a integer as
159 large as a pointer, Python's *VoidPtr interface is the
160 most appropriate here */
161 return PyLong_FromVoidPtr((void*)handle);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000162}
163
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000164PyDoc_STRVAR(get_osfhandle_doc,
165"get_osfhandle(fd) -> file handle\n\
166\n\
167Return the file handle for the file descriptor fd. Raises IOError\n\
168if fd is not recognized.");
169
Guido van Rossum407a22d1997-08-13 19:57:53 +0000170/* Console I/O */
Guido van Rossum407a22d1997-08-13 19:57:53 +0000171
Tim Peters5fa0bd62000-12-12 01:58:56 +0000172static PyObject *
173msvcrt_kbhit(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 int ok;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 if (!PyArg_ParseTuple(args, ":kbhit"))
178 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 ok = _kbhit();
181 return PyLong_FromLong(ok);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000182}
183
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000184PyDoc_STRVAR(kbhit_doc,
185"kbhit() -> bool\n\
186\n\
187Return true if a keypress is waiting to be read.");
188
Tim Peters5fa0bd62000-12-12 01:58:56 +0000189static PyObject *
190msvcrt_getch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000191{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 int ch;
193 char s[1];
Guido van Rossum407a22d1997-08-13 19:57:53 +0000194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 if (!PyArg_ParseTuple(args, ":getch"))
196 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 Py_BEGIN_ALLOW_THREADS
199 ch = _getch();
200 Py_END_ALLOW_THREADS
201 s[0] = ch;
202 return PyBytes_FromStringAndSize(s, 1);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000203}
204
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000205PyDoc_STRVAR(getch_doc,
206"getch() -> key character\n\
207\n\
Brian Curtin8790a072010-08-24 05:20:30 +0000208Read a keypress and return the resulting character as a byte string.\n\
209Nothing is echoed to the console. This call will block if a keypress is\n\
210not already available, but will not wait for Enter to be pressed. If the\n\
211pressed key was a special function key, this will return '\\000' or\n\
212'\\xe0'; the next call will return the keycode. The Control-C keypress\n\
213cannot be read with this function.");
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000214
Amaury Forgeot d'Arc3d17a5c2008-06-13 01:09:34 +0000215#ifdef _WCONIO_DEFINED
Tim Peters5fa0bd62000-12-12 01:58:56 +0000216static PyObject *
Christian Heimes2f1019e2007-12-10 16:18:49 +0000217msvcrt_getwch(PyObject *self, PyObject *args)
218{
Victor Stinner9d3b93b2011-11-22 02:27:30 +0100219 wchar_t ch;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000221 if (!PyArg_ParseTuple(args, ":getwch"))
222 return NULL;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 Py_BEGIN_ALLOW_THREADS
225 ch = _getwch();
226 Py_END_ALLOW_THREADS
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200227 return PyUnicode_FromOrdinal(ch);
Christian Heimes2f1019e2007-12-10 16:18:49 +0000228}
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000229
230PyDoc_STRVAR(getwch_doc,
231"getwch() -> Unicode key character\n\
232\n\
233Wide char variant of getch(), returning a Unicode value.");
Christian Heimesc36625b2008-01-04 13:33:00 +0000234#endif
Christian Heimes2f1019e2007-12-10 16:18:49 +0000235
236static PyObject *
Tim Peters5fa0bd62000-12-12 01:58:56 +0000237msvcrt_getche(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000238{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 int ch;
240 char s[1];
Guido van Rossum407a22d1997-08-13 19:57:53 +0000241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 if (!PyArg_ParseTuple(args, ":getche"))
243 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 Py_BEGIN_ALLOW_THREADS
246 ch = _getche();
247 Py_END_ALLOW_THREADS
248 s[0] = ch;
249 return PyBytes_FromStringAndSize(s, 1);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000250}
251
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000252PyDoc_STRVAR(getche_doc,
253"getche() -> key character\n\
254\n\
255Similar to getch(), but the keypress will be echoed if it represents\n\
256a printable character.");
257
Amaury Forgeot d'Arc3d17a5c2008-06-13 01:09:34 +0000258#ifdef _WCONIO_DEFINED
Tim Peters5fa0bd62000-12-12 01:58:56 +0000259static PyObject *
Christian Heimes2f1019e2007-12-10 16:18:49 +0000260msvcrt_getwche(PyObject *self, PyObject *args)
261{
Victor Stinner9d3b93b2011-11-22 02:27:30 +0100262 wchar_t ch;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 if (!PyArg_ParseTuple(args, ":getwche"))
265 return NULL;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 Py_BEGIN_ALLOW_THREADS
268 ch = _getwche();
269 Py_END_ALLOW_THREADS
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200270 return PyUnicode_FromOrdinal(ch);
Christian Heimes2f1019e2007-12-10 16:18:49 +0000271}
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000272
273PyDoc_STRVAR(getwche_doc,
274"getwche() -> Unicode key character\n\
275\n\
276Wide char variant of getche(), returning a Unicode value.");
Christian Heimesc36625b2008-01-04 13:33:00 +0000277#endif
Christian Heimes2f1019e2007-12-10 16:18:49 +0000278
279static PyObject *
Tim Peters5fa0bd62000-12-12 01:58:56 +0000280msvcrt_putch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000281{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 char ch;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 if (!PyArg_ParseTuple(args, "c:putch", &ch))
285 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 _putch(ch);
288 Py_INCREF(Py_None);
289 return Py_None;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000290}
291
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000292PyDoc_STRVAR(putch_doc,
293"putch(char) -> None\n\
294\n\
Brian Curtin8790a072010-08-24 05:20:30 +0000295Print the byte string char to the console without buffering.");
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000296
Amaury Forgeot d'Arc3d17a5c2008-06-13 01:09:34 +0000297#ifdef _WCONIO_DEFINED
Christian Heimes2f1019e2007-12-10 16:18:49 +0000298static PyObject *
299msvcrt_putwch(PyObject *self, PyObject *args)
300{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 int ch;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 if (!PyArg_ParseTuple(args, "C:putwch", &ch))
304 return NULL;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 _putwch(ch);
307 Py_RETURN_NONE;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000308
309}
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000310
311PyDoc_STRVAR(putwch_doc,
312"putwch(unicode_char) -> None\n\
313\n\
314Wide char variant of putch(), accepting a Unicode value.");
Christian Heimesc36625b2008-01-04 13:33:00 +0000315#endif
Christian Heimes2f1019e2007-12-10 16:18:49 +0000316
Tim Peters5fa0bd62000-12-12 01:58:56 +0000317static PyObject *
318msvcrt_ungetch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000319{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 char ch;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 if (!PyArg_ParseTuple(args, "c:ungetch", &ch))
323 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 if (_ungetch(ch) == EOF)
326 return PyErr_SetFromErrno(PyExc_IOError);
327 Py_INCREF(Py_None);
328 return Py_None;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000329}
330
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000331PyDoc_STRVAR(ungetch_doc,
332"ungetch(char) -> None\n\
333\n\
Brian Curtin8790a072010-08-24 05:20:30 +0000334Cause the byte string char to be \"pushed back\" into the\n\
335console buffer; it will be the next character read by\n\
336getch() or getche().");
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000337
Amaury Forgeot d'Arc3d17a5c2008-06-13 01:09:34 +0000338#ifdef _WCONIO_DEFINED
Christian Heimes2f1019e2007-12-10 16:18:49 +0000339static PyObject *
340msvcrt_ungetwch(PyObject *self, PyObject *args)
341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342 int ch;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000344 if (!PyArg_ParseTuple(args, "C:ungetwch", &ch))
345 return NULL;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 if (_ungetwch(ch) == WEOF)
348 return PyErr_SetFromErrno(PyExc_IOError);
349 Py_INCREF(Py_None);
350 return Py_None;
Christian Heimes2f1019e2007-12-10 16:18:49 +0000351}
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000352
353PyDoc_STRVAR(ungetwch_doc,
354"ungetwch(unicode_char) -> None\n\
355\n\
356Wide char variant of ungetch(), accepting a Unicode value.");
Christian Heimesc36625b2008-01-04 13:33:00 +0000357#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000358
Tim Peters5fa0bd62000-12-12 01:58:56 +0000359static void
360insertint(PyObject *d, char *name, int value)
361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 PyObject *v = PyLong_FromLong((long) value);
363 if (v == NULL) {
364 /* Don't bother reporting this error */
365 PyErr_Clear();
366 }
367 else {
368 PyDict_SetItemString(d, name, v);
369 Py_DECREF(v);
370 }
Tim Peters5fa0bd62000-12-12 01:58:56 +0000371}
372
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000373#ifdef _DEBUG
374
375static PyObject*
376msvcrt_setreportfile(PyObject *self, PyObject *args)
377{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 int type, file;
379 _HFILE res;
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 if (!PyArg_ParseTuple(args, "ii", &type, &file))
382 return NULL;
383 res = _CrtSetReportFile(type, (_HFILE)file);
384 return PyLong_FromLong((long)res);
385 Py_INCREF(Py_None);
386 return Py_None;
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000387}
388
389static PyObject*
390msvcrt_setreportmode(PyObject *self, PyObject *args)
391{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392 int type, mode;
393 int res;
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 if (!PyArg_ParseTuple(args, "ii", &type, &mode))
396 return NULL;
397 res = _CrtSetReportMode(type, mode);
398 if (res == -1)
399 return PyErr_SetFromErrno(PyExc_IOError);
400 return PyLong_FromLong(res);
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000401}
402
403static PyObject*
404msvcrt_seterrormode(PyObject *self, PyObject *args)
405{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 int mode, res;
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 if (!PyArg_ParseTuple(args, "i", &mode))
409 return NULL;
410 res = _set_error_mode(mode);
411 return PyLong_FromLong(res);
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000412}
413
414#endif
415
416static PyObject*
417seterrormode(PyObject *self, PyObject *args)
418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 unsigned int mode, res;
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 if (!PyArg_ParseTuple(args, "I", &mode))
422 return NULL;
423 res = SetErrorMode(mode);
424 return PyLong_FromUnsignedLong(res);
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000425}
426
Tim Peters5fa0bd62000-12-12 01:58:56 +0000427
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000428/* List of functions exported by this module */
429static struct PyMethodDef msvcrt_functions[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000430 {"heapmin", msvcrt_heapmin, METH_VARARGS, heapmin_doc},
431 {"locking", msvcrt_locking, METH_VARARGS, locking_doc},
432 {"setmode", msvcrt_setmode, METH_VARARGS, setmode_doc},
433 {"open_osfhandle", msvcrt_open_osfhandle, METH_VARARGS, open_osfhandle_doc},
434 {"get_osfhandle", msvcrt_get_osfhandle, METH_VARARGS, get_osfhandle_doc},
435 {"kbhit", msvcrt_kbhit, METH_VARARGS, kbhit_doc},
436 {"getch", msvcrt_getch, METH_VARARGS, getch_doc},
437 {"getche", msvcrt_getche, METH_VARARGS, getche_doc},
438 {"putch", msvcrt_putch, METH_VARARGS, putch_doc},
439 {"ungetch", msvcrt_ungetch, METH_VARARGS, ungetch_doc},
440 {"SetErrorMode", seterrormode, METH_VARARGS},
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000441#ifdef _DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 {"CrtSetReportFile", msvcrt_setreportfile, METH_VARARGS},
443 {"CrtSetReportMode", msvcrt_setreportmode, METH_VARARGS},
444 {"set_error_mode", msvcrt_seterrormode, METH_VARARGS},
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000445#endif
Amaury Forgeot d'Arc3d17a5c2008-06-13 01:09:34 +0000446#ifdef _WCONIO_DEFINED
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 {"getwch", msvcrt_getwch, METH_VARARGS, getwch_doc},
448 {"getwche", msvcrt_getwche, METH_VARARGS, getwche_doc},
449 {"putwch", msvcrt_putwch, METH_VARARGS, putwch_doc},
450 {"ungetwch", msvcrt_ungetwch, METH_VARARGS, ungetwch_doc},
Christian Heimesc36625b2008-01-04 13:33:00 +0000451#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 {NULL, NULL}
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000453};
454
Martin v. Löwis1a214512008-06-11 05:26:20 +0000455
456static struct PyModuleDef msvcrtmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457 PyModuleDef_HEAD_INIT,
458 "msvcrt",
459 NULL,
460 -1,
461 msvcrt_functions,
462 NULL,
463 NULL,
464 NULL,
465 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000466};
467
Thomas Hellera18331d2004-07-28 20:02:52 +0000468PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000469PyInit_msvcrt(void)
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 int st;
Brian Curtin401f9f32012-05-13 11:19:23 -0500472 PyObject *d, *version;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 PyObject *m = PyModule_Create(&msvcrtmodule);
474 if (m == NULL)
475 return NULL;
476 d = PyModule_GetDict(m);
Tim Peters5fa0bd62000-12-12 01:58:56 +0000477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 /* constants for the locking() function's mode argument */
479 insertint(d, "LK_LOCK", _LK_LOCK);
480 insertint(d, "LK_NBLCK", _LK_NBLCK);
481 insertint(d, "LK_NBRLCK", _LK_NBRLCK);
482 insertint(d, "LK_RLCK", _LK_RLCK);
483 insertint(d, "LK_UNLCK", _LK_UNLCK);
484 insertint(d, "SEM_FAILCRITICALERRORS", SEM_FAILCRITICALERRORS);
485 insertint(d, "SEM_NOALIGNMENTFAULTEXCEPT", SEM_NOALIGNMENTFAULTEXCEPT);
486 insertint(d, "SEM_NOGPFAULTERRORBOX", SEM_NOGPFAULTERRORBOX);
487 insertint(d, "SEM_NOOPENFILEERRORBOX", SEM_NOOPENFILEERRORBOX);
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000488#ifdef _DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 insertint(d, "CRT_WARN", _CRT_WARN);
490 insertint(d, "CRT_ERROR", _CRT_ERROR);
491 insertint(d, "CRT_ASSERT", _CRT_ASSERT);
492 insertint(d, "CRTDBG_MODE_DEBUG", _CRTDBG_MODE_DEBUG);
493 insertint(d, "CRTDBG_MODE_FILE", _CRTDBG_MODE_FILE);
494 insertint(d, "CRTDBG_MODE_WNDW", _CRTDBG_MODE_WNDW);
495 insertint(d, "CRTDBG_REPORT_MODE", _CRTDBG_REPORT_MODE);
496 insertint(d, "CRTDBG_FILE_STDERR", (int)_CRTDBG_FILE_STDERR);
497 insertint(d, "CRTDBG_FILE_STDOUT", (int)_CRTDBG_FILE_STDOUT);
498 insertint(d, "CRTDBG_REPORT_FILE", (int)_CRTDBG_REPORT_FILE);
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000499#endif
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 /* constants for the crt versions */
Brian Curtin401f9f32012-05-13 11:19:23 -0500502 (void)st;
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000503#ifdef _VC_ASSEMBLY_PUBLICKEYTOKEN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 st = PyModule_AddStringConstant(m, "VC_ASSEMBLY_PUBLICKEYTOKEN",
505 _VC_ASSEMBLY_PUBLICKEYTOKEN);
506 if (st < 0) return NULL;
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000507#endif
508#ifdef _CRT_ASSEMBLY_VERSION
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 st = PyModule_AddStringConstant(m, "CRT_ASSEMBLY_VERSION",
510 _CRT_ASSEMBLY_VERSION);
511 if (st < 0) return NULL;
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000512#endif
513#ifdef __LIBRARIES_ASSEMBLY_NAME_PREFIX
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 st = PyModule_AddStringConstant(m, "LIBRARIES_ASSEMBLY_NAME_PREFIX",
515 __LIBRARIES_ASSEMBLY_NAME_PREFIX);
516 if (st < 0) return NULL;
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000517#endif
518
Brian Curtin401f9f32012-05-13 11:19:23 -0500519 /* constants for the 2010 crt versions */
520#if defined(_VC_CRT_MAJOR_VERSION) && defined (_VC_CRT_MINOR_VERSION) && defined(_VC_CRT_BUILD_VERSION) && defined(_VC_CRT_RBUILD_VERSION)
521 version = PyUnicode_FromFormat("%d.%d.%d.%d", _VC_CRT_MAJOR_VERSION,
522 _VC_CRT_MINOR_VERSION,
523 _VC_CRT_BUILD_VERSION,
524 _VC_CRT_RBUILD_VERSION);
525 st = PyModule_AddObject(m, "CRT_ASSEMBLY_VERSION", version);
526 if (st < 0) return NULL;
527#endif
528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 return m;
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000530}