blob: cad22b19e0a0d3ae31b0a9be851ad6c0d8395bce [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>
Guido van Rossum29c1ea51997-08-07 00:11:34 +000024
Martin v. Löwisbcb017f2008-11-30 19:28:27 +000025#ifdef _MSC_VER
26#if _MSC_VER >= 1500
27#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{
Guido van Rossum407a22d1997-08-13 19:57:53 +000036 if (!PyArg_ParseTuple(args, ":heapmin"))
Guido van Rossum29c1ea51997-08-07 00:11:34 +000037 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +000038
39 if (_heapmin() != 0)
40 return PyErr_SetFromErrno(PyExc_IOError);
41
Guido van Rossum29c1ea51997-08-07 00:11:34 +000042 Py_INCREF(Py_None);
43 return Py_None;
44}
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{
Guido van Rossum407a22d1997-08-13 19:57:53 +000050 int fd;
51 int mode;
52 long nbytes;
Guido van Rossume4e021b1998-05-29 01:27:07 +000053 int err;
Guido van Rossum407a22d1997-08-13 19:57:53 +000054
55 if (!PyArg_ParseTuple(args, "iil:locking", &fd, &mode, &nbytes))
Guido van Rossum29c1ea51997-08-07 00:11:34 +000056 return NULL;
57
Guido van Rossume4e021b1998-05-29 01:27:07 +000058 Py_BEGIN_ALLOW_THREADS
59 err = _locking(fd, mode, nbytes);
60 Py_END_ALLOW_THREADS
61 if (err != 0)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000062 return PyErr_SetFromErrno(PyExc_IOError);
63
Guido van Rossum407a22d1997-08-13 19:57:53 +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{
72 int fd;
73 int flags;
74 if (!PyArg_ParseTuple(args,"ii:setmode", &fd, &flags))
75 return NULL;
76
77 flags = _setmode(fd, flags);
78 if (flags == -1)
79 return PyErr_SetFromErrno(PyExc_IOError);
80
81 return PyInt_FromLong(flags);
82}
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{
88 long handle;
89 int flags;
90 int fd;
91
92 if (!PyArg_ParseTuple(args, "li:open_osfhandle", &handle, &flags))
Guido van Rossume4e021b1998-05-29 01:27:07 +000093 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +000094
95 fd = _open_osfhandle(handle, flags);
96 if (fd == -1)
97 return PyErr_SetFromErrno(PyExc_IOError);
98
99 return PyInt_FromLong(fd);
100}
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{
106 int fd;
Tim Peters79248aa2001-08-29 21:37:10 +0000107 Py_intptr_t handle;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000108
109 if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd))
110 return NULL;
111
112 handle = _get_osfhandle(fd);
113 if (handle == -1)
114 return PyErr_SetFromErrno(PyExc_IOError);
115
Fred Drake25e17262000-06-30 17:48:51 +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{
127 int ok;
128
129 if (!PyArg_ParseTuple(args, ":kbhit"))
130 return NULL;
131
132 ok = _kbhit();
133 return PyInt_FromLong(ok);
134}
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{
139 int ch;
140 char s[1];
141
142 if (!PyArg_ParseTuple(args, ":getch"))
143 return NULL;
144
Guido van Rossume4e021b1998-05-29 01:27:07 +0000145 Py_BEGIN_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000146 ch = _getch();
Guido van Rossume4e021b1998-05-29 01:27:07 +0000147 Py_END_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000148 s[0] = ch;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000149 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{
156 Py_UNICODE ch;
157 Py_UNICODE u[1];
158
159 if (!PyArg_ParseTuple(args, ":getwch"))
160 return NULL;
161
162 Py_BEGIN_ALLOW_THREADS
163 ch = _getwch();
164 Py_END_ALLOW_THREADS
165 u[0] = ch;
166 return PyUnicode_FromUnicode(u, 1);
167}
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{
173 int ch;
174 char s[1];
175
176 if (!PyArg_ParseTuple(args, ":getche"))
177 return NULL;
178
Guido van Rossume4e021b1998-05-29 01:27:07 +0000179 Py_BEGIN_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000180 ch = _getche();
Guido van Rossume4e021b1998-05-29 01:27:07 +0000181 Py_END_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000182 s[0] = ch;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000183 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{
190 Py_UNICODE ch;
191 Py_UNICODE s[1];
192
193 if (!PyArg_ParseTuple(args, ":getwche"))
194 return NULL;
195
196 Py_BEGIN_ALLOW_THREADS
197 ch = _getwche();
198 Py_END_ALLOW_THREADS
199 s[0] = ch;
200 return PyUnicode_FromUnicode(s, 1);
201}
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{
207 char ch;
208
209 if (!PyArg_ParseTuple(args, "c:putch", &ch))
210 return NULL;
211
212 _putch(ch);
213 Py_INCREF(Py_None);
214 return Py_None;
215}
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{
221 Py_UNICODE *ch;
222 int size;
223
224 if (!PyArg_ParseTuple(args, "u#:putwch", &ch, &size))
225 return NULL;
226
Christian Heimes61927fc2007-12-10 15:39:09 +0000227 if (size == 0) {
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000228 PyErr_SetString(PyExc_ValueError,
Christian Heimes61927fc2007-12-10 15:39:09 +0000229 "Expected unicode string of length 1");
230 return NULL;
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000231 }
Christian Heimes61927fc2007-12-10 15:39:09 +0000232 _putwch(*ch);
233 Py_RETURN_NONE;
234
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{
241 char ch;
242
243 if (!PyArg_ParseTuple(args, "c:ungetch", &ch))
244 return NULL;
245
Guido van Rossum6543e881999-02-16 19:40:02 +0000246 if (_ungetch(ch) == EOF)
247 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000248 Py_INCREF(Py_None);
249 return Py_None;
250}
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{
256 Py_UNICODE ch;
257
258 if (!PyArg_ParseTuple(args, "u:ungetwch", &ch))
259 return NULL;
260
261 if (_ungetch(ch) == EOF)
262 return PyErr_SetFromErrno(PyExc_IOError);
263 Py_INCREF(Py_None);
264 return Py_None;
265}
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{
271 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 }
280}
281
282
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000283/* List of functions exported by this module */
284static struct PyMethodDef msvcrt_functions[] = {
Neal Norwitz031829d2002-03-31 14:37:44 +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
Christian Heimes7c7f6af2007-12-10 15:12:41 +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
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000301 {NULL, NULL}
302};
303
Thomas Hellera18331d2004-07-28 20:02:52 +0000304PyMODINIT_FUNC
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000305initmsvcrt(void)
306{
Martin v. Löwisbcb017f2008-11-30 19:28:27 +0000307 int st;
Tim Peters2188bf02006-01-19 15:21:30 +0000308 PyObject *d;
Tim Peters5fa0bd62000-12-12 01:58:56 +0000309 PyObject *m = Py_InitModule("msvcrt", msvcrt_functions);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000310 if (m == NULL)
311 return;
Tim Peters2188bf02006-01-19 15:21:30 +0000312 d = PyModule_GetDict(m);
Tim Peters5fa0bd62000-12-12 01:58:56 +0000313
314 /* 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öwisbcb017f2008-11-30 19:28:27 +0000320
321 /* constants for the crt versions */
322#ifdef _VC_ASSEMBLY_PUBLICKEYTOKEN
323 st = PyModule_AddStringConstant(m, "VC_ASSEMBLY_PUBLICKEYTOKEN",
324 _VC_ASSEMBLY_PUBLICKEYTOKEN);
325 if (st < 0)return;
326#endif
327#ifdef _CRT_ASSEMBLY_VERSION
328 st = PyModule_AddStringConstant(m, "CRT_ASSEMBLY_VERSION",
329 _CRT_ASSEMBLY_VERSION);
330 if (st < 0)return;
331#endif
332#ifdef __LIBRARIES_ASSEMBLY_NAME_PREFIX
333 st = PyModule_AddStringConstant(m, "LIBRARIES_ASSEMBLY_NAME_PREFIX",
334 __LIBRARIES_ASSEMBLY_NAME_PREFIX);
335 if (st < 0)return;
336#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000337}