blob: 225121f6424f63dd2d408e022d513c231ef4aef3 [file] [log] [blame]
Guido van Rossum29c1ea51997-08-07 00:11:34 +00001/*********************************************************
2
3 msvcrtmodule.c
4
5 A Python interface to the Microsoft Visual C Runtime
6 Library, providing access to those non-portable, but
7 still useful routines.
8
9 Only ever compiled with an MS compiler, so no attempt
10 has been made to avoid MS language extensions, etc...
11
Guido van Rossum407a22d1997-08-13 19:57:53 +000012 This may only work on NT or 95...
13
14 Author: Mark Hammond and Guido van Rossum.
15 Maintenance: Guido van Rossum.
16
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
Guido van Rossum407a22d1997-08-13 19:57:53 +000027// Force the malloc heap to clean itself up, and free unused blocks
28// back to the OS. (According to the docs, only works on NT.)
Tim Peters5fa0bd62000-12-12 01:58:56 +000029static PyObject *
30msvcrt_heapmin(PyObject *self, PyObject *args)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000031{
Guido van Rossum407a22d1997-08-13 19:57:53 +000032 if (!PyArg_ParseTuple(args, ":heapmin"))
Guido van Rossum29c1ea51997-08-07 00:11:34 +000033 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +000034
35 if (_heapmin() != 0)
36 return PyErr_SetFromErrno(PyExc_IOError);
37
Guido van Rossum29c1ea51997-08-07 00:11:34 +000038 Py_INCREF(Py_None);
39 return Py_None;
40}
41
Guido van Rossum407a22d1997-08-13 19:57:53 +000042// Perform locking operations on a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000043static PyObject *
44msvcrt_locking(PyObject *self, PyObject *args)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000045{
Guido van Rossum407a22d1997-08-13 19:57:53 +000046 int fd;
47 int mode;
48 long nbytes;
Guido van Rossume4e021b1998-05-29 01:27:07 +000049 int err;
Guido van Rossum407a22d1997-08-13 19:57:53 +000050
51 if (!PyArg_ParseTuple(args, "iil:locking", &fd, &mode, &nbytes))
Guido van Rossum29c1ea51997-08-07 00:11:34 +000052 return NULL;
53
Guido van Rossume4e021b1998-05-29 01:27:07 +000054 Py_BEGIN_ALLOW_THREADS
55 err = _locking(fd, mode, nbytes);
56 Py_END_ALLOW_THREADS
57 if (err != 0)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000058 return PyErr_SetFromErrno(PyExc_IOError);
59
Guido van Rossum407a22d1997-08-13 19:57:53 +000060 Py_INCREF(Py_None);
61 return Py_None;
Guido van Rossum29c1ea51997-08-07 00:11:34 +000062}
Guido van Rossum407a22d1997-08-13 19:57:53 +000063
64// Set the file translation mode for a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000065static PyObject *
66msvcrt_setmode(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +000067{
68 int fd;
69 int flags;
70 if (!PyArg_ParseTuple(args,"ii:setmode", &fd, &flags))
71 return NULL;
72
73 flags = _setmode(fd, flags);
74 if (flags == -1)
75 return PyErr_SetFromErrno(PyExc_IOError);
76
Christian Heimes217cfd12007-12-02 14:31:20 +000077 return PyLong_FromLong(flags);
Guido van Rossum407a22d1997-08-13 19:57:53 +000078}
79
80// Convert an OS file handle to a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000081static PyObject *
82msvcrt_open_osfhandle(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +000083{
84 long handle;
85 int flags;
86 int fd;
87
88 if (!PyArg_ParseTuple(args, "li:open_osfhandle", &handle, &flags))
Guido van Rossume4e021b1998-05-29 01:27:07 +000089 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +000090
91 fd = _open_osfhandle(handle, flags);
92 if (fd == -1)
93 return PyErr_SetFromErrno(PyExc_IOError);
94
Christian Heimes217cfd12007-12-02 14:31:20 +000095 return PyLong_FromLong(fd);
Guido van Rossum407a22d1997-08-13 19:57:53 +000096}
97
98// Convert a C runtime file descriptor to an OS file handle.
Tim Peters5fa0bd62000-12-12 01:58:56 +000099static PyObject *
100msvcrt_get_osfhandle(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000101{
102 int fd;
Tim Peters79248aa2001-08-29 21:37:10 +0000103 Py_intptr_t handle;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000104
105 if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd))
106 return NULL;
107
108 handle = _get_osfhandle(fd);
109 if (handle == -1)
110 return PyErr_SetFromErrno(PyExc_IOError);
111
Fred Drake25e17262000-06-30 17:48:51 +0000112 /* technically 'handle' is not a pointer, but a integer as
113 large as a pointer, Python's *VoidPtr interface is the
114 most appropriate here */
115 return PyLong_FromVoidPtr((void*)handle);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000116}
117
118/* Console I/O */
Guido van Rossum407a22d1997-08-13 19:57:53 +0000119
Tim Peters5fa0bd62000-12-12 01:58:56 +0000120static PyObject *
121msvcrt_kbhit(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000122{
123 int ok;
124
125 if (!PyArg_ParseTuple(args, ":kbhit"))
126 return NULL;
127
128 ok = _kbhit();
Christian Heimes217cfd12007-12-02 14:31:20 +0000129 return PyLong_FromLong(ok);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000130}
131
Tim Peters5fa0bd62000-12-12 01:58:56 +0000132static PyObject *
133msvcrt_getch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000134{
135 int ch;
136 char s[1];
137
138 if (!PyArg_ParseTuple(args, ":getch"))
139 return NULL;
140
Guido van Rossume4e021b1998-05-29 01:27:07 +0000141 Py_BEGIN_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000142 ch = _getch();
Guido van Rossume4e021b1998-05-29 01:27:07 +0000143 Py_END_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000144 s[0] = ch;
Christian Heimes72b710a2008-05-26 13:28:38 +0000145 return PyBytes_FromStringAndSize(s, 1);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000146}
147
Christian Heimesc36625b2008-01-04 13:33:00 +0000148#if _MSC_VER >= 1300
Tim Peters5fa0bd62000-12-12 01:58:56 +0000149static PyObject *
Christian Heimes2f1019e2007-12-10 16:18:49 +0000150msvcrt_getwch(PyObject *self, PyObject *args)
151{
152 Py_UNICODE ch;
153 Py_UNICODE u[1];
154
155 if (!PyArg_ParseTuple(args, ":getwch"))
156 return NULL;
157
158 Py_BEGIN_ALLOW_THREADS
159 ch = _getwch();
160 Py_END_ALLOW_THREADS
161 u[0] = ch;
162 return PyUnicode_FromUnicode(u, 1);
163}
Christian Heimesc36625b2008-01-04 13:33:00 +0000164#endif
Christian Heimes2f1019e2007-12-10 16:18:49 +0000165
166static PyObject *
Tim Peters5fa0bd62000-12-12 01:58:56 +0000167msvcrt_getche(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000168{
169 int ch;
170 char s[1];
171
172 if (!PyArg_ParseTuple(args, ":getche"))
173 return NULL;
174
Guido van Rossume4e021b1998-05-29 01:27:07 +0000175 Py_BEGIN_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000176 ch = _getche();
Guido van Rossume4e021b1998-05-29 01:27:07 +0000177 Py_END_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000178 s[0] = ch;
Christian Heimes72b710a2008-05-26 13:28:38 +0000179 return PyBytes_FromStringAndSize(s, 1);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000180}
181
Christian Heimesc36625b2008-01-04 13:33:00 +0000182#if _MSC_VER >= 1300
Tim Peters5fa0bd62000-12-12 01:58:56 +0000183static PyObject *
Christian Heimes2f1019e2007-12-10 16:18:49 +0000184msvcrt_getwche(PyObject *self, PyObject *args)
185{
186 Py_UNICODE ch;
187 Py_UNICODE s[1];
188
189 if (!PyArg_ParseTuple(args, ":getwche"))
190 return NULL;
191
192 Py_BEGIN_ALLOW_THREADS
193 ch = _getwche();
194 Py_END_ALLOW_THREADS
195 s[0] = ch;
196 return PyUnicode_FromUnicode(s, 1);
197}
Christian Heimesc36625b2008-01-04 13:33:00 +0000198#endif
Christian Heimes2f1019e2007-12-10 16:18:49 +0000199
200static PyObject *
Tim Peters5fa0bd62000-12-12 01:58:56 +0000201msvcrt_putch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000202{
203 char ch;
204
205 if (!PyArg_ParseTuple(args, "c:putch", &ch))
206 return NULL;
207
208 _putch(ch);
209 Py_INCREF(Py_None);
210 return Py_None;
211}
212
Christian Heimes2f1019e2007-12-10 16:18:49 +0000213
Christian Heimesc36625b2008-01-04 13:33:00 +0000214#if _MSC_VER >= 1300
Christian Heimes2f1019e2007-12-10 16:18:49 +0000215static PyObject *
216msvcrt_putwch(PyObject *self, PyObject *args)
217{
218 Py_UNICODE *ch;
219 int size;
220
221 if (!PyArg_ParseTuple(args, "u#:putwch", &ch, &size))
222 return NULL;
223
224 if (size == 0) {
225 PyErr_SetString(PyExc_ValueError,
226 "Expected unicode string of length 1");
227 return NULL;
228 }
229 _putwch(*ch);
230 Py_RETURN_NONE;
231
232}
Christian Heimesc36625b2008-01-04 13:33:00 +0000233#endif
Christian Heimes2f1019e2007-12-10 16:18:49 +0000234
Tim Peters5fa0bd62000-12-12 01:58:56 +0000235static PyObject *
236msvcrt_ungetch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000237{
238 char ch;
239
240 if (!PyArg_ParseTuple(args, "c:ungetch", &ch))
241 return NULL;
242
Guido van Rossum6543e881999-02-16 19:40:02 +0000243 if (_ungetch(ch) == EOF)
244 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000245 Py_INCREF(Py_None);
246 return Py_None;
247}
248
Christian Heimesc36625b2008-01-04 13:33:00 +0000249#if _MSC_VER >= 1300
Christian Heimes2f1019e2007-12-10 16:18:49 +0000250static PyObject *
251msvcrt_ungetwch(PyObject *self, PyObject *args)
252{
253 Py_UNICODE ch;
254
255 if (!PyArg_ParseTuple(args, "u:ungetwch", &ch))
256 return NULL;
257
258 if (_ungetch(ch) == EOF)
259 return PyErr_SetFromErrno(PyExc_IOError);
260 Py_INCREF(Py_None);
261 return Py_None;
262}
Christian Heimesc36625b2008-01-04 13:33:00 +0000263#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000264
Tim Peters5fa0bd62000-12-12 01:58:56 +0000265static void
266insertint(PyObject *d, char *name, int value)
267{
Christian Heimes217cfd12007-12-02 14:31:20 +0000268 PyObject *v = PyLong_FromLong((long) value);
Tim Peters5fa0bd62000-12-12 01:58:56 +0000269 if (v == NULL) {
270 /* Don't bother reporting this error */
271 PyErr_Clear();
272 }
273 else {
274 PyDict_SetItemString(d, name, v);
275 Py_DECREF(v);
276 }
277}
278
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000279#ifdef _DEBUG
280
281static PyObject*
282msvcrt_setreportfile(PyObject *self, PyObject *args)
283{
284 int type, file;
285 _HFILE res;
286
287 if (!PyArg_ParseTuple(args, "ii", &type, &file))
288 return NULL;
289 res = _CrtSetReportFile(type, (_HFILE)file);
Christian Heimes217cfd12007-12-02 14:31:20 +0000290 return PyLong_FromLong((long)res);
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000291 Py_INCREF(Py_None);
292 return Py_None;
293}
294
295static PyObject*
296msvcrt_setreportmode(PyObject *self, PyObject *args)
297{
298 int type, mode;
299 int res;
300
301 if (!PyArg_ParseTuple(args, "ii", &type, &mode))
302 return NULL;
303 res = _CrtSetReportMode(type, mode);
304 if (res == -1)
305 return PyErr_SetFromErrno(PyExc_IOError);
306 return PyLong_FromLong(res);
307}
308
309static PyObject*
310msvcrt_seterrormode(PyObject *self, PyObject *args)
311{
312 int mode, res;
313
314 if (!PyArg_ParseTuple(args, "i", &mode))
315 return NULL;
316 res = _set_error_mode(mode);
317 return PyLong_FromLong(res);
318}
319
320#endif
321
322static PyObject*
323seterrormode(PyObject *self, PyObject *args)
324{
325 unsigned int mode, res;
326
327 if (!PyArg_ParseTuple(args, "I", &mode))
328 return NULL;
329 res = SetErrorMode(mode);
330 return PyLong_FromUnsignedLong(res);
331}
332
Tim Peters5fa0bd62000-12-12 01:58:56 +0000333
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000334/* List of functions exported by this module */
335static struct PyMethodDef msvcrt_functions[] = {
Neal Norwitz031829d2002-03-31 14:37:44 +0000336 {"heapmin", msvcrt_heapmin, METH_VARARGS},
337 {"locking", msvcrt_locking, METH_VARARGS},
338 {"setmode", msvcrt_setmode, METH_VARARGS},
339 {"open_osfhandle", msvcrt_open_osfhandle, METH_VARARGS},
340 {"get_osfhandle", msvcrt_get_osfhandle, METH_VARARGS},
341 {"kbhit", msvcrt_kbhit, METH_VARARGS},
342 {"getch", msvcrt_getch, METH_VARARGS},
343 {"getche", msvcrt_getche, METH_VARARGS},
344 {"putch", msvcrt_putch, METH_VARARGS},
345 {"ungetch", msvcrt_ungetch, METH_VARARGS},
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000346 {"SetErrorMode", seterrormode, METH_VARARGS},
347#ifdef _DEBUG
348 {"CrtSetReportFile", msvcrt_setreportfile, METH_VARARGS},
349 {"CrtSetReportMode", msvcrt_setreportmode, METH_VARARGS},
350 {"set_error_mode", msvcrt_seterrormode, METH_VARARGS},
351#endif
Christian Heimesc36625b2008-01-04 13:33:00 +0000352#if _MSC_VER >= 1300
Christian Heimes2f1019e2007-12-10 16:18:49 +0000353 {"getwch", msvcrt_getwch, METH_VARARGS},
354 {"getwche", msvcrt_getwche, METH_VARARGS},
355 {"putwch", msvcrt_putwch, METH_VARARGS},
356 {"ungetwch", msvcrt_ungetwch, METH_VARARGS},
Christian Heimesc36625b2008-01-04 13:33:00 +0000357#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000358 {NULL, NULL}
359};
360
Martin v. Löwis1a214512008-06-11 05:26:20 +0000361
362static struct PyModuleDef msvcrtmodule = {
363 PyModuleDef_HEAD_INIT,
364 "msvcrt",
365 NULL,
366 -1,
367 msvcrt_functions,
368 NULL,
369 NULL,
370 NULL,
371 NULL
372};
373
Thomas Hellera18331d2004-07-28 20:02:52 +0000374PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000375PyInit_msvcrt(void)
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000376{
Tim Peters2188bf02006-01-19 15:21:30 +0000377 PyObject *d;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000378 PyObject *m = PyModule_Create(&msvcrtmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000379 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000380 return NULL;
Tim Peters2188bf02006-01-19 15:21:30 +0000381 d = PyModule_GetDict(m);
Tim Peters5fa0bd62000-12-12 01:58:56 +0000382
383 /* constants for the locking() function's mode argument */
384 insertint(d, "LK_LOCK", _LK_LOCK);
385 insertint(d, "LK_NBLCK", _LK_NBLCK);
386 insertint(d, "LK_NBRLCK", _LK_NBRLCK);
387 insertint(d, "LK_RLCK", _LK_RLCK);
388 insertint(d, "LK_UNLCK", _LK_UNLCK);
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000389 insertint(d, "SEM_FAILCRITICALERRORS", SEM_FAILCRITICALERRORS);
390 insertint(d, "SEM_NOALIGNMENTFAULTEXCEPT", SEM_NOALIGNMENTFAULTEXCEPT);
391 insertint(d, "SEM_NOGPFAULTERRORBOX", SEM_NOGPFAULTERRORBOX);
392 insertint(d, "SEM_NOOPENFILEERRORBOX", SEM_NOOPENFILEERRORBOX);
393#ifdef _DEBUG
394 insertint(d, "CRT_WARN", _CRT_WARN);
395 insertint(d, "CRT_ERROR", _CRT_ERROR);
396 insertint(d, "CRT_ASSERT", _CRT_ASSERT);
397 insertint(d, "CRTDBG_MODE_DEBUG", _CRTDBG_MODE_DEBUG);
398 insertint(d, "CRTDBG_MODE_FILE", _CRTDBG_MODE_FILE);
399 insertint(d, "CRTDBG_MODE_WNDW", _CRTDBG_MODE_WNDW);
400 insertint(d, "CRTDBG_REPORT_MODE", _CRTDBG_REPORT_MODE);
401 insertint(d, "CRTDBG_FILE_STDERR", (int)_CRTDBG_FILE_STDERR);
402 insertint(d, "CRTDBG_FILE_STDOUT", (int)_CRTDBG_FILE_STDOUT);
403 insertint(d, "CRTDBG_REPORT_FILE", (int)_CRTDBG_REPORT_FILE);
404#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +0000405 return m;
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000406}