blob: f441aa386c895fa8d84f084d598d9bd8dc123e2f [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
Benjamin Peterson4469d0c2008-11-30 22:46:23 +000027#ifdef _MSC_VER
28#if _MSC_VER >= 1500
29#include <crtassem.h>
30#endif
31#endif
32
Guido van Rossum407a22d1997-08-13 19:57:53 +000033// Force the malloc heap to clean itself up, and free unused blocks
34// back to the OS. (According to the docs, only works on NT.)
Tim Peters5fa0bd62000-12-12 01:58:56 +000035static PyObject *
36msvcrt_heapmin(PyObject *self, PyObject *args)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000037{
Guido van Rossum407a22d1997-08-13 19:57:53 +000038 if (!PyArg_ParseTuple(args, ":heapmin"))
Guido van Rossum29c1ea51997-08-07 00:11:34 +000039 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +000040
41 if (_heapmin() != 0)
42 return PyErr_SetFromErrno(PyExc_IOError);
43
Guido van Rossum29c1ea51997-08-07 00:11:34 +000044 Py_INCREF(Py_None);
45 return Py_None;
46}
47
Guido van Rossum407a22d1997-08-13 19:57:53 +000048// Perform locking operations on a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000049static PyObject *
50msvcrt_locking(PyObject *self, PyObject *args)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000051{
Guido van Rossum407a22d1997-08-13 19:57:53 +000052 int fd;
53 int mode;
54 long nbytes;
Guido van Rossume4e021b1998-05-29 01:27:07 +000055 int err;
Guido van Rossum407a22d1997-08-13 19:57:53 +000056
57 if (!PyArg_ParseTuple(args, "iil:locking", &fd, &mode, &nbytes))
Guido van Rossum29c1ea51997-08-07 00:11:34 +000058 return NULL;
59
Guido van Rossume4e021b1998-05-29 01:27:07 +000060 Py_BEGIN_ALLOW_THREADS
61 err = _locking(fd, mode, nbytes);
62 Py_END_ALLOW_THREADS
63 if (err != 0)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000064 return PyErr_SetFromErrno(PyExc_IOError);
65
Guido van Rossum407a22d1997-08-13 19:57:53 +000066 Py_INCREF(Py_None);
67 return Py_None;
Guido van Rossum29c1ea51997-08-07 00:11:34 +000068}
Guido van Rossum407a22d1997-08-13 19:57:53 +000069
70// Set the file translation mode for a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000071static PyObject *
72msvcrt_setmode(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +000073{
74 int fd;
75 int flags;
76 if (!PyArg_ParseTuple(args,"ii:setmode", &fd, &flags))
77 return NULL;
78
79 flags = _setmode(fd, flags);
80 if (flags == -1)
81 return PyErr_SetFromErrno(PyExc_IOError);
82
Christian Heimes217cfd12007-12-02 14:31:20 +000083 return PyLong_FromLong(flags);
Guido van Rossum407a22d1997-08-13 19:57:53 +000084}
85
86// Convert an OS file handle to a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000087static PyObject *
88msvcrt_open_osfhandle(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +000089{
90 long handle;
91 int flags;
92 int fd;
93
94 if (!PyArg_ParseTuple(args, "li:open_osfhandle", &handle, &flags))
Guido van Rossume4e021b1998-05-29 01:27:07 +000095 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +000096
97 fd = _open_osfhandle(handle, flags);
98 if (fd == -1)
99 return PyErr_SetFromErrno(PyExc_IOError);
100
Christian Heimes217cfd12007-12-02 14:31:20 +0000101 return PyLong_FromLong(fd);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000102}
103
104// Convert a C runtime file descriptor to an OS file handle.
Tim Peters5fa0bd62000-12-12 01:58:56 +0000105static PyObject *
106msvcrt_get_osfhandle(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000107{
108 int fd;
Tim Peters79248aa2001-08-29 21:37:10 +0000109 Py_intptr_t handle;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000110
111 if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd))
112 return NULL;
113
114 handle = _get_osfhandle(fd);
115 if (handle == -1)
116 return PyErr_SetFromErrno(PyExc_IOError);
117
Fred Drake25e17262000-06-30 17:48:51 +0000118 /* technically 'handle' is not a pointer, but a integer as
119 large as a pointer, Python's *VoidPtr interface is the
120 most appropriate here */
121 return PyLong_FromVoidPtr((void*)handle);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000122}
123
124/* Console I/O */
Guido van Rossum407a22d1997-08-13 19:57:53 +0000125
Tim Peters5fa0bd62000-12-12 01:58:56 +0000126static PyObject *
127msvcrt_kbhit(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000128{
129 int ok;
130
131 if (!PyArg_ParseTuple(args, ":kbhit"))
132 return NULL;
133
134 ok = _kbhit();
Christian Heimes217cfd12007-12-02 14:31:20 +0000135 return PyLong_FromLong(ok);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000136}
137
Tim Peters5fa0bd62000-12-12 01:58:56 +0000138static PyObject *
139msvcrt_getch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000140{
141 int ch;
142 char s[1];
143
144 if (!PyArg_ParseTuple(args, ":getch"))
145 return NULL;
146
Guido van Rossume4e021b1998-05-29 01:27:07 +0000147 Py_BEGIN_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000148 ch = _getch();
Guido van Rossume4e021b1998-05-29 01:27:07 +0000149 Py_END_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000150 s[0] = ch;
Christian Heimes72b710a2008-05-26 13:28:38 +0000151 return PyBytes_FromStringAndSize(s, 1);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000152}
153
Amaury Forgeot d'Arc3d17a5c2008-06-13 01:09:34 +0000154#ifdef _WCONIO_DEFINED
Tim Peters5fa0bd62000-12-12 01:58:56 +0000155static PyObject *
Christian Heimes2f1019e2007-12-10 16:18:49 +0000156msvcrt_getwch(PyObject *self, PyObject *args)
157{
158 Py_UNICODE ch;
159 Py_UNICODE u[1];
160
161 if (!PyArg_ParseTuple(args, ":getwch"))
162 return NULL;
163
164 Py_BEGIN_ALLOW_THREADS
165 ch = _getwch();
166 Py_END_ALLOW_THREADS
167 u[0] = ch;
168 return PyUnicode_FromUnicode(u, 1);
169}
Christian Heimesc36625b2008-01-04 13:33:00 +0000170#endif
Christian Heimes2f1019e2007-12-10 16:18:49 +0000171
172static PyObject *
Tim Peters5fa0bd62000-12-12 01:58:56 +0000173msvcrt_getche(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000174{
175 int ch;
176 char s[1];
177
178 if (!PyArg_ParseTuple(args, ":getche"))
179 return NULL;
180
Guido van Rossume4e021b1998-05-29 01:27:07 +0000181 Py_BEGIN_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000182 ch = _getche();
Guido van Rossume4e021b1998-05-29 01:27:07 +0000183 Py_END_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000184 s[0] = ch;
Christian Heimes72b710a2008-05-26 13:28:38 +0000185 return PyBytes_FromStringAndSize(s, 1);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000186}
187
Amaury Forgeot d'Arc3d17a5c2008-06-13 01:09:34 +0000188#ifdef _WCONIO_DEFINED
Tim Peters5fa0bd62000-12-12 01:58:56 +0000189static PyObject *
Christian Heimes2f1019e2007-12-10 16:18:49 +0000190msvcrt_getwche(PyObject *self, PyObject *args)
191{
192 Py_UNICODE ch;
193 Py_UNICODE s[1];
194
195 if (!PyArg_ParseTuple(args, ":getwche"))
196 return NULL;
197
198 Py_BEGIN_ALLOW_THREADS
199 ch = _getwche();
200 Py_END_ALLOW_THREADS
201 s[0] = ch;
202 return PyUnicode_FromUnicode(s, 1);
203}
Christian Heimesc36625b2008-01-04 13:33:00 +0000204#endif
Christian Heimes2f1019e2007-12-10 16:18:49 +0000205
206static PyObject *
Tim Peters5fa0bd62000-12-12 01:58:56 +0000207msvcrt_putch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000208{
209 char ch;
210
211 if (!PyArg_ParseTuple(args, "c:putch", &ch))
212 return NULL;
213
214 _putch(ch);
215 Py_INCREF(Py_None);
216 return Py_None;
217}
218
Amaury Forgeot d'Arc3d17a5c2008-06-13 01:09:34 +0000219#ifdef _WCONIO_DEFINED
Christian Heimes2f1019e2007-12-10 16:18:49 +0000220static PyObject *
221msvcrt_putwch(PyObject *self, PyObject *args)
222{
223 Py_UNICODE *ch;
224 int size;
225
226 if (!PyArg_ParseTuple(args, "u#:putwch", &ch, &size))
227 return NULL;
228
229 if (size == 0) {
230 PyErr_SetString(PyExc_ValueError,
231 "Expected unicode string of length 1");
232 return NULL;
233 }
234 _putwch(*ch);
235 Py_RETURN_NONE;
236
237}
Christian Heimesc36625b2008-01-04 13:33:00 +0000238#endif
Christian Heimes2f1019e2007-12-10 16:18:49 +0000239
Tim Peters5fa0bd62000-12-12 01:58:56 +0000240static PyObject *
241msvcrt_ungetch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000242{
243 char ch;
244
245 if (!PyArg_ParseTuple(args, "c:ungetch", &ch))
246 return NULL;
247
Guido van Rossum6543e881999-02-16 19:40:02 +0000248 if (_ungetch(ch) == EOF)
249 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000250 Py_INCREF(Py_None);
251 return Py_None;
252}
253
Amaury Forgeot d'Arc3d17a5c2008-06-13 01:09:34 +0000254#ifdef _WCONIO_DEFINED
Christian Heimes2f1019e2007-12-10 16:18:49 +0000255static PyObject *
256msvcrt_ungetwch(PyObject *self, PyObject *args)
257{
258 Py_UNICODE ch;
259
260 if (!PyArg_ParseTuple(args, "u:ungetwch", &ch))
261 return NULL;
262
263 if (_ungetch(ch) == EOF)
264 return PyErr_SetFromErrno(PyExc_IOError);
265 Py_INCREF(Py_None);
266 return Py_None;
267}
Christian Heimesc36625b2008-01-04 13:33:00 +0000268#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000269
Tim Peters5fa0bd62000-12-12 01:58:56 +0000270static void
271insertint(PyObject *d, char *name, int value)
272{
Christian Heimes217cfd12007-12-02 14:31:20 +0000273 PyObject *v = PyLong_FromLong((long) value);
Tim Peters5fa0bd62000-12-12 01:58:56 +0000274 if (v == NULL) {
275 /* Don't bother reporting this error */
276 PyErr_Clear();
277 }
278 else {
279 PyDict_SetItemString(d, name, v);
280 Py_DECREF(v);
281 }
282}
283
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000284#ifdef _DEBUG
285
286static PyObject*
287msvcrt_setreportfile(PyObject *self, PyObject *args)
288{
289 int type, file;
290 _HFILE res;
291
292 if (!PyArg_ParseTuple(args, "ii", &type, &file))
293 return NULL;
294 res = _CrtSetReportFile(type, (_HFILE)file);
Christian Heimes217cfd12007-12-02 14:31:20 +0000295 return PyLong_FromLong((long)res);
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000296 Py_INCREF(Py_None);
297 return Py_None;
298}
299
300static PyObject*
301msvcrt_setreportmode(PyObject *self, PyObject *args)
302{
303 int type, mode;
304 int res;
305
306 if (!PyArg_ParseTuple(args, "ii", &type, &mode))
307 return NULL;
308 res = _CrtSetReportMode(type, mode);
309 if (res == -1)
310 return PyErr_SetFromErrno(PyExc_IOError);
311 return PyLong_FromLong(res);
312}
313
314static PyObject*
315msvcrt_seterrormode(PyObject *self, PyObject *args)
316{
317 int mode, res;
318
319 if (!PyArg_ParseTuple(args, "i", &mode))
320 return NULL;
321 res = _set_error_mode(mode);
322 return PyLong_FromLong(res);
323}
324
325#endif
326
327static PyObject*
328seterrormode(PyObject *self, PyObject *args)
329{
330 unsigned int mode, res;
331
332 if (!PyArg_ParseTuple(args, "I", &mode))
333 return NULL;
334 res = SetErrorMode(mode);
335 return PyLong_FromUnsignedLong(res);
336}
337
Tim Peters5fa0bd62000-12-12 01:58:56 +0000338
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000339/* List of functions exported by this module */
340static struct PyMethodDef msvcrt_functions[] = {
Neal Norwitz031829d2002-03-31 14:37:44 +0000341 {"heapmin", msvcrt_heapmin, METH_VARARGS},
342 {"locking", msvcrt_locking, METH_VARARGS},
343 {"setmode", msvcrt_setmode, METH_VARARGS},
344 {"open_osfhandle", msvcrt_open_osfhandle, METH_VARARGS},
345 {"get_osfhandle", msvcrt_get_osfhandle, METH_VARARGS},
346 {"kbhit", msvcrt_kbhit, METH_VARARGS},
347 {"getch", msvcrt_getch, METH_VARARGS},
348 {"getche", msvcrt_getche, METH_VARARGS},
349 {"putch", msvcrt_putch, METH_VARARGS},
350 {"ungetch", msvcrt_ungetch, METH_VARARGS},
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000351 {"SetErrorMode", seterrormode, METH_VARARGS},
352#ifdef _DEBUG
353 {"CrtSetReportFile", msvcrt_setreportfile, METH_VARARGS},
354 {"CrtSetReportMode", msvcrt_setreportmode, METH_VARARGS},
355 {"set_error_mode", msvcrt_seterrormode, METH_VARARGS},
356#endif
Amaury Forgeot d'Arc3d17a5c2008-06-13 01:09:34 +0000357#ifdef _WCONIO_DEFINED
Christian Heimes2f1019e2007-12-10 16:18:49 +0000358 {"getwch", msvcrt_getwch, METH_VARARGS},
359 {"getwche", msvcrt_getwche, METH_VARARGS},
360 {"putwch", msvcrt_putwch, METH_VARARGS},
361 {"ungetwch", msvcrt_ungetwch, METH_VARARGS},
Christian Heimesc36625b2008-01-04 13:33:00 +0000362#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000363 {NULL, NULL}
364};
365
Martin v. Löwis1a214512008-06-11 05:26:20 +0000366
367static struct PyModuleDef msvcrtmodule = {
368 PyModuleDef_HEAD_INIT,
369 "msvcrt",
370 NULL,
371 -1,
372 msvcrt_functions,
373 NULL,
374 NULL,
375 NULL,
376 NULL
377};
378
Thomas Hellera18331d2004-07-28 20:02:52 +0000379PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000380PyInit_msvcrt(void)
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000381{
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000382 int st;
Tim Peters2188bf02006-01-19 15:21:30 +0000383 PyObject *d;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000384 PyObject *m = PyModule_Create(&msvcrtmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000385 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000386 return NULL;
Tim Peters2188bf02006-01-19 15:21:30 +0000387 d = PyModule_GetDict(m);
Tim Peters5fa0bd62000-12-12 01:58:56 +0000388
389 /* constants for the locking() function's mode argument */
390 insertint(d, "LK_LOCK", _LK_LOCK);
391 insertint(d, "LK_NBLCK", _LK_NBLCK);
392 insertint(d, "LK_NBRLCK", _LK_NBRLCK);
393 insertint(d, "LK_RLCK", _LK_RLCK);
394 insertint(d, "LK_UNLCK", _LK_UNLCK);
Martin v. Löwis3dc33d12007-08-31 07:58:36 +0000395 insertint(d, "SEM_FAILCRITICALERRORS", SEM_FAILCRITICALERRORS);
396 insertint(d, "SEM_NOALIGNMENTFAULTEXCEPT", SEM_NOALIGNMENTFAULTEXCEPT);
397 insertint(d, "SEM_NOGPFAULTERRORBOX", SEM_NOGPFAULTERRORBOX);
398 insertint(d, "SEM_NOOPENFILEERRORBOX", SEM_NOOPENFILEERRORBOX);
399#ifdef _DEBUG
400 insertint(d, "CRT_WARN", _CRT_WARN);
401 insertint(d, "CRT_ERROR", _CRT_ERROR);
402 insertint(d, "CRT_ASSERT", _CRT_ASSERT);
403 insertint(d, "CRTDBG_MODE_DEBUG", _CRTDBG_MODE_DEBUG);
404 insertint(d, "CRTDBG_MODE_FILE", _CRTDBG_MODE_FILE);
405 insertint(d, "CRTDBG_MODE_WNDW", _CRTDBG_MODE_WNDW);
406 insertint(d, "CRTDBG_REPORT_MODE", _CRTDBG_REPORT_MODE);
407 insertint(d, "CRTDBG_FILE_STDERR", (int)_CRTDBG_FILE_STDERR);
408 insertint(d, "CRTDBG_FILE_STDOUT", (int)_CRTDBG_FILE_STDOUT);
409 insertint(d, "CRTDBG_REPORT_FILE", (int)_CRTDBG_REPORT_FILE);
410#endif
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000411
412 /* constants for the crt versions */
413#ifdef _VC_ASSEMBLY_PUBLICKEYTOKEN
414 st = PyModule_AddStringConstant(m, "VC_ASSEMBLY_PUBLICKEYTOKEN",
415 _VC_ASSEMBLY_PUBLICKEYTOKEN);
416 if (st < 0) return NULL;
417#endif
418#ifdef _CRT_ASSEMBLY_VERSION
419 st = PyModule_AddStringConstant(m, "CRT_ASSEMBLY_VERSION",
420 _CRT_ASSEMBLY_VERSION);
421 if (st < 0) return NULL;
422#endif
423#ifdef __LIBRARIES_ASSEMBLY_NAME_PREFIX
424 st = PyModule_AddStringConstant(m, "LIBRARIES_ASSEMBLY_NAME_PREFIX",
425 __LIBRARIES_ASSEMBLY_NAME_PREFIX);
426 if (st < 0) return NULL;
427#endif
428
429 return m;
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000430}