blob: 418965d748158490b46b2cc79fcbfc1a4d111356 [file] [log] [blame]
Guido van Rossum29c1ea51997-08-07 00:11:34 +00001/*********************************************************
2
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003 msvcrtmodule.c
Guido van Rossum29c1ea51997-08-07 00:11:34 +00004
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +000012 This may only work on NT or 95...
Guido van Rossum407a22d1997-08-13 19:57:53 +000013
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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>
Guido van Rossum29c1ea51997-08-07 00:11:34 +000024
Martin v. Löwis1d8592b2008-12-01 04:49:40 +000025#ifdef _MSC_VER
Martin v. Löwis7f898e32010-02-18 16:24:56 +000026#if _MSC_VER >= 1500 && _MSC_VER < 1600
Martin v. Löwis1d8592b2008-12-01 04:49:40 +000027#include <crtassem.h>
28#endif
29#endif
30
Guido van Rossum407a22d1997-08-13 19:57:53 +000031// Force the malloc heap to clean itself up, and free unused blocks
32// back to the OS. (According to the docs, only works on NT.)
Tim Peters5fa0bd62000-12-12 01:58:56 +000033static PyObject *
34msvcrt_heapmin(PyObject *self, PyObject *args)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000035{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000036 if (!PyArg_ParseTuple(args, ":heapmin"))
37 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +000038
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000039 if (_heapmin() != 0)
40 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum407a22d1997-08-13 19:57:53 +000041
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000042 Py_INCREF(Py_None);
43 return Py_None;
Guido van Rossum29c1ea51997-08-07 00:11:34 +000044}
45
Guido van Rossum407a22d1997-08-13 19:57:53 +000046// Perform locking operations on a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000047static PyObject *
48msvcrt_locking(PyObject *self, PyObject *args)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000049{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000050 int fd;
51 int mode;
52 long nbytes;
53 int err;
Guido van Rossum407a22d1997-08-13 19:57:53 +000054
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000055 if (!PyArg_ParseTuple(args, "iil:locking", &fd, &mode, &nbytes))
56 return NULL;
Guido van Rossum29c1ea51997-08-07 00:11:34 +000057
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000058 Py_BEGIN_ALLOW_THREADS
59 err = _locking(fd, mode, nbytes);
60 Py_END_ALLOW_THREADS
61 if (err != 0)
62 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum29c1ea51997-08-07 00:11:34 +000063
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000064 Py_INCREF(Py_None);
65 return Py_None;
Guido van Rossum29c1ea51997-08-07 00:11:34 +000066}
Guido van Rossum407a22d1997-08-13 19:57:53 +000067
68// Set the file translation mode for a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000069static PyObject *
70msvcrt_setmode(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +000071{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000072 int fd;
73 int flags;
74 if (!PyArg_ParseTuple(args,"ii:setmode", &fd, &flags))
75 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +000076
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000077 flags = _setmode(fd, flags);
78 if (flags == -1)
79 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum407a22d1997-08-13 19:57:53 +000080
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000081 return PyInt_FromLong(flags);
Guido van Rossum407a22d1997-08-13 19:57:53 +000082}
83
84// Convert an OS file handle to a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000085static PyObject *
86msvcrt_open_osfhandle(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +000087{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000088 long handle;
89 int flags;
90 int fd;
Guido van Rossum407a22d1997-08-13 19:57:53 +000091
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000092 if (!PyArg_ParseTuple(args, "li:open_osfhandle", &handle, &flags))
93 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +000094
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000095 fd = _open_osfhandle(handle, flags);
96 if (fd == -1)
97 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum407a22d1997-08-13 19:57:53 +000098
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000099 return PyInt_FromLong(fd);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000100}
101
102// Convert a C runtime file descriptor to an OS file handle.
Tim Peters5fa0bd62000-12-12 01:58:56 +0000103static PyObject *
104msvcrt_get_osfhandle(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000105{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000106 int fd;
107 Py_intptr_t handle;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000108
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000109 if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd))
110 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000111
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000112 handle = _get_osfhandle(fd);
113 if (handle == -1)
114 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000115
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000116 /* technically 'handle' is not a pointer, but a integer as
117 large as a pointer, Python's *VoidPtr interface is the
118 most appropriate here */
119 return PyLong_FromVoidPtr((void*)handle);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000120}
121
122/* Console I/O */
Guido van Rossum407a22d1997-08-13 19:57:53 +0000123
Tim Peters5fa0bd62000-12-12 01:58:56 +0000124static PyObject *
125msvcrt_kbhit(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000126{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000127 int ok;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000128
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000129 if (!PyArg_ParseTuple(args, ":kbhit"))
130 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000131
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000132 ok = _kbhit();
133 return PyInt_FromLong(ok);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000134}
135
Tim Peters5fa0bd62000-12-12 01:58:56 +0000136static PyObject *
137msvcrt_getch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000138{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000139 int ch;
140 char s[1];
Guido van Rossum407a22d1997-08-13 19:57:53 +0000141
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000142 if (!PyArg_ParseTuple(args, ":getch"))
143 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000144
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000145 Py_BEGIN_ALLOW_THREADS
146 ch = _getch();
147 Py_END_ALLOW_THREADS
148 s[0] = ch;
149 return PyString_FromStringAndSize(s, 1);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000150}
151
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000152#ifdef _WCONIO_DEFINED
Tim Peters5fa0bd62000-12-12 01:58:56 +0000153static PyObject *
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000154msvcrt_getwch(PyObject *self, PyObject *args)
155{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000156 Py_UNICODE ch;
157 Py_UNICODE u[1];
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000158
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000159 if (!PyArg_ParseTuple(args, ":getwch"))
160 return NULL;
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000161
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000162 Py_BEGIN_ALLOW_THREADS
163 ch = _getwch();
164 Py_END_ALLOW_THREADS
165 u[0] = ch;
166 return PyUnicode_FromUnicode(u, 1);
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000167}
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000168#endif
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000169
170static PyObject *
Tim Peters5fa0bd62000-12-12 01:58:56 +0000171msvcrt_getche(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000172{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000173 int ch;
174 char s[1];
Guido van Rossum407a22d1997-08-13 19:57:53 +0000175
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000176 if (!PyArg_ParseTuple(args, ":getche"))
177 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000178
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000179 Py_BEGIN_ALLOW_THREADS
180 ch = _getche();
181 Py_END_ALLOW_THREADS
182 s[0] = ch;
183 return PyString_FromStringAndSize(s, 1);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000184}
185
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000186#ifdef _WCONIO_DEFINED
Tim Peters5fa0bd62000-12-12 01:58:56 +0000187static PyObject *
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000188msvcrt_getwche(PyObject *self, PyObject *args)
189{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000190 Py_UNICODE ch;
191 Py_UNICODE s[1];
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000192
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000193 if (!PyArg_ParseTuple(args, ":getwche"))
194 return NULL;
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000195
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000196 Py_BEGIN_ALLOW_THREADS
197 ch = _getwche();
198 Py_END_ALLOW_THREADS
199 s[0] = ch;
200 return PyUnicode_FromUnicode(s, 1);
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000201}
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000202#endif
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000203
204static PyObject *
Tim Peters5fa0bd62000-12-12 01:58:56 +0000205msvcrt_putch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000206{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000207 char ch;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000208
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000209 if (!PyArg_ParseTuple(args, "c:putch", &ch))
210 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000211
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000212 _putch(ch);
213 Py_INCREF(Py_None);
214 return Py_None;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000215}
216
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000217#ifdef _WCONIO_DEFINED
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000218static PyObject *
219msvcrt_putwch(PyObject *self, PyObject *args)
220{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000221 Py_UNICODE *ch;
222 int size;
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000223
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000224 if (!PyArg_ParseTuple(args, "u#:putwch", &ch, &size))
225 return NULL;
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000226
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000227 if (size == 0) {
228 PyErr_SetString(PyExc_ValueError,
229 "Expected unicode string of length 1");
230 return NULL;
231 }
232 _putwch(*ch);
233 Py_RETURN_NONE;
Christian Heimes61927fc2007-12-10 15:39:09 +0000234
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000235}
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000236#endif
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000237
Tim Peters5fa0bd62000-12-12 01:58:56 +0000238static PyObject *
239msvcrt_ungetch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000240{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000241 char ch;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000242
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000243 if (!PyArg_ParseTuple(args, "c:ungetch", &ch))
244 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000245
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000246 if (_ungetch(ch) == EOF)
247 return PyErr_SetFromErrno(PyExc_IOError);
248 Py_INCREF(Py_None);
249 return Py_None;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000250}
251
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000252#ifdef _WCONIO_DEFINED
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000253static PyObject *
254msvcrt_ungetwch(PyObject *self, PyObject *args)
255{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000256 Py_UNICODE ch;
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000257
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000258 if (!PyArg_ParseTuple(args, "u:ungetwch", &ch))
259 return NULL;
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000260
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000261 if (_ungetch(ch) == EOF)
262 return PyErr_SetFromErrno(PyExc_IOError);
263 Py_INCREF(Py_None);
264 return Py_None;
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000265}
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000266#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000267
Tim Peters5fa0bd62000-12-12 01:58:56 +0000268static void
269insertint(PyObject *d, char *name, int value)
270{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000271 PyObject *v = PyInt_FromLong((long) value);
272 if (v == NULL) {
273 /* Don't bother reporting this error */
274 PyErr_Clear();
275 }
276 else {
277 PyDict_SetItemString(d, name, v);
278 Py_DECREF(v);
279 }
Tim Peters5fa0bd62000-12-12 01:58:56 +0000280}
281
282
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000283/* List of functions exported by this module */
284static struct PyMethodDef msvcrt_functions[] = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000285 {"heapmin", msvcrt_heapmin, METH_VARARGS},
286 {"locking", msvcrt_locking, METH_VARARGS},
287 {"setmode", msvcrt_setmode, METH_VARARGS},
288 {"open_osfhandle", msvcrt_open_osfhandle, METH_VARARGS},
289 {"get_osfhandle", msvcrt_get_osfhandle, METH_VARARGS},
290 {"kbhit", msvcrt_kbhit, METH_VARARGS},
291 {"getch", msvcrt_getch, METH_VARARGS},
292 {"getche", msvcrt_getche, METH_VARARGS},
293 {"putch", msvcrt_putch, METH_VARARGS},
294 {"ungetch", msvcrt_ungetch, METH_VARARGS},
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000295#ifdef _WCONIO_DEFINED
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000296 {"getwch", msvcrt_getwch, METH_VARARGS},
297 {"getwche", msvcrt_getwche, METH_VARARGS},
298 {"putwch", msvcrt_putwch, METH_VARARGS},
299 {"ungetwch", msvcrt_ungetwch, METH_VARARGS},
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000300#endif
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000301 {NULL, NULL}
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000302};
303
Thomas Hellera18331d2004-07-28 20:02:52 +0000304PyMODINIT_FUNC
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000305initmsvcrt(void)
306{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000307 int st;
308 PyObject *d;
309 PyObject *m = Py_InitModule("msvcrt", msvcrt_functions);
310 if (m == NULL)
311 return;
312 d = PyModule_GetDict(m);
Tim Peters5fa0bd62000-12-12 01:58:56 +0000313
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000314 /* constants for the locking() function's mode argument */
315 insertint(d, "LK_LOCK", _LK_LOCK);
316 insertint(d, "LK_NBLCK", _LK_NBLCK);
317 insertint(d, "LK_NBRLCK", _LK_NBRLCK);
318 insertint(d, "LK_RLCK", _LK_RLCK);
319 insertint(d, "LK_UNLCK", _LK_UNLCK);
Martin v. Löwis1d8592b2008-12-01 04:49:40 +0000320
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000321 /* constants for the crt versions */
Martin v. Löwis1d8592b2008-12-01 04:49:40 +0000322#ifdef _VC_ASSEMBLY_PUBLICKEYTOKEN
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000323 st = PyModule_AddStringConstant(m, "VC_ASSEMBLY_PUBLICKEYTOKEN",
324 _VC_ASSEMBLY_PUBLICKEYTOKEN);
325 if (st < 0)return;
Martin v. Löwis1d8592b2008-12-01 04:49:40 +0000326#endif
327#ifdef _CRT_ASSEMBLY_VERSION
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000328 st = PyModule_AddStringConstant(m, "CRT_ASSEMBLY_VERSION",
329 _CRT_ASSEMBLY_VERSION);
330 if (st < 0)return;
Martin v. Löwis1d8592b2008-12-01 04:49:40 +0000331#endif
332#ifdef __LIBRARIES_ASSEMBLY_NAME_PREFIX
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000333 st = PyModule_AddStringConstant(m, "LIBRARIES_ASSEMBLY_NAME_PREFIX",
334 __LIBRARIES_ASSEMBLY_NAME_PREFIX);
335 if (st < 0)return;
Martin v. Löwis1d8592b2008-12-01 04:49:40 +0000336#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000337}