blob: 6e804e454f7dfcf3a58a4bb22a00eba72bdd2209 [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
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +000046PyDoc_STRVAR(heapmin_doc,
47"heapmin() -> None\n\
48\n\
49Force the malloc() heap to clean itself up and return unused blocks\n\
Georg Brandlb7953f02009-12-30 19:03:00 +000050to the operating system. On failure, this raises IOError.");
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +000051
Guido van Rossum407a22d1997-08-13 19:57:53 +000052// Perform locking operations on a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000053static PyObject *
54msvcrt_locking(PyObject *self, PyObject *args)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000055{
Guido van Rossum407a22d1997-08-13 19:57:53 +000056 int fd;
57 int mode;
58 long nbytes;
Guido van Rossume4e021b1998-05-29 01:27:07 +000059 int err;
Guido van Rossum407a22d1997-08-13 19:57:53 +000060
61 if (!PyArg_ParseTuple(args, "iil:locking", &fd, &mode, &nbytes))
Guido van Rossum29c1ea51997-08-07 00:11:34 +000062 return NULL;
63
Guido van Rossume4e021b1998-05-29 01:27:07 +000064 Py_BEGIN_ALLOW_THREADS
65 err = _locking(fd, mode, nbytes);
66 Py_END_ALLOW_THREADS
67 if (err != 0)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000068 return PyErr_SetFromErrno(PyExc_IOError);
69
Guido van Rossum407a22d1997-08-13 19:57:53 +000070 Py_INCREF(Py_None);
71 return Py_None;
Guido van Rossum29c1ea51997-08-07 00:11:34 +000072}
Guido van Rossum407a22d1997-08-13 19:57:53 +000073
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +000074PyDoc_STRVAR(locking_doc,
75"locking(fd, mode, nbytes) -> None\n\
76\n\
77Lock part of a file based on file descriptor fd from the C runtime.\n\
78Raises IOError on failure. The locked region of the file extends from\n\
79the current file position for nbytes bytes, and may continue beyond\n\
80the end of the file. mode must be one of the LK_* constants listed\n\
81below. Multiple regions in a file may be locked at the same time, but\n\
82may not overlap. Adjacent regions are not merged; they must be unlocked\n\
83individually.");
84
Guido van Rossum407a22d1997-08-13 19:57:53 +000085// Set the file translation mode for a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000086static PyObject *
87msvcrt_setmode(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +000088{
89 int fd;
90 int flags;
91 if (!PyArg_ParseTuple(args,"ii:setmode", &fd, &flags))
92 return NULL;
93
94 flags = _setmode(fd, flags);
95 if (flags == -1)
96 return PyErr_SetFromErrno(PyExc_IOError);
97
98 return PyInt_FromLong(flags);
99}
100
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000101PyDoc_STRVAR(setmode_doc,
102"setmode(fd, mode) -> Previous mode\n\
103\n\
104Set the line-end translation mode for the file descriptor fd. To set\n\
105it to text mode, flags should be os.O_TEXT; for binary, it should be\n\
106os.O_BINARY.");
107
Guido van Rossum407a22d1997-08-13 19:57:53 +0000108// Convert an OS file handle to a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +0000109static PyObject *
110msvcrt_open_osfhandle(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000111{
112 long handle;
113 int flags;
114 int fd;
115
116 if (!PyArg_ParseTuple(args, "li:open_osfhandle", &handle, &flags))
Guido van Rossume4e021b1998-05-29 01:27:07 +0000117 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000118
119 fd = _open_osfhandle(handle, flags);
120 if (fd == -1)
121 return PyErr_SetFromErrno(PyExc_IOError);
122
123 return PyInt_FromLong(fd);
124}
125
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000126PyDoc_STRVAR(open_osfhandle_doc,
127"open_osfhandle(handle, flags) -> file descriptor\n\
128\n\
129Create a C runtime file descriptor from the file handle handle. The\n\
130flags parameter should be a bitwise OR of os.O_APPEND, os.O_RDONLY,\n\
131and os.O_TEXT. The returned file descriptor may be used as a parameter\n\
132to os.fdopen() to create a file object.");
133
Guido van Rossum407a22d1997-08-13 19:57:53 +0000134// Convert a C runtime file descriptor to an OS file handle.
Tim Peters5fa0bd62000-12-12 01:58:56 +0000135static PyObject *
136msvcrt_get_osfhandle(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000137{
138 int fd;
Tim Peters79248aa2001-08-29 21:37:10 +0000139 Py_intptr_t handle;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000140
141 if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd))
142 return NULL;
143
144 handle = _get_osfhandle(fd);
145 if (handle == -1)
146 return PyErr_SetFromErrno(PyExc_IOError);
147
Fred Drake25e17262000-06-30 17:48:51 +0000148 /* technically 'handle' is not a pointer, but a integer as
149 large as a pointer, Python's *VoidPtr interface is the
150 most appropriate here */
151 return PyLong_FromVoidPtr((void*)handle);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000152}
153
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000154PyDoc_STRVAR(get_osfhandle_doc,
155"get_osfhandle(fd) -> file handle\n\
156\n\
157Return the file handle for the file descriptor fd. Raises IOError\n\
158if fd is not recognized.");
159
Guido van Rossum407a22d1997-08-13 19:57:53 +0000160/* Console I/O */
Guido van Rossum407a22d1997-08-13 19:57:53 +0000161
Tim Peters5fa0bd62000-12-12 01:58:56 +0000162static PyObject *
163msvcrt_kbhit(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000164{
165 int ok;
166
167 if (!PyArg_ParseTuple(args, ":kbhit"))
168 return NULL;
169
170 ok = _kbhit();
171 return PyInt_FromLong(ok);
172}
173
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000174PyDoc_STRVAR(kbhit_doc,
175"kbhit() -> bool\n\
176\n\
177Return true if a keypress is waiting to be read.");
178
Tim Peters5fa0bd62000-12-12 01:58:56 +0000179static PyObject *
180msvcrt_getch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000181{
182 int ch;
183 char s[1];
184
185 if (!PyArg_ParseTuple(args, ":getch"))
186 return NULL;
187
Guido van Rossume4e021b1998-05-29 01:27:07 +0000188 Py_BEGIN_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000189 ch = _getch();
Guido van Rossume4e021b1998-05-29 01:27:07 +0000190 Py_END_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000191 s[0] = ch;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000192 return PyString_FromStringAndSize(s, 1);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000193}
194
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000195PyDoc_STRVAR(getch_doc,
196"getch() -> key character\n\
197\n\
198Read a keypress and return the resulting character. Nothing is echoed to\n\
199the console. This call will block if a keypress is not already\n\
200available, but will not wait for Enter to be pressed. If the pressed key\n\
201was a special function key, this will return '\\000' or '\\xe0'; the next\n\
202call will return the keycode. The Control-C keypress cannot be read with\n\
203this function.");
204
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000205#ifdef _WCONIO_DEFINED
Tim Peters5fa0bd62000-12-12 01:58:56 +0000206static PyObject *
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000207msvcrt_getwch(PyObject *self, PyObject *args)
208{
209 Py_UNICODE ch;
210 Py_UNICODE u[1];
211
212 if (!PyArg_ParseTuple(args, ":getwch"))
213 return NULL;
214
215 Py_BEGIN_ALLOW_THREADS
216 ch = _getwch();
217 Py_END_ALLOW_THREADS
218 u[0] = ch;
219 return PyUnicode_FromUnicode(u, 1);
220}
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000221
222PyDoc_STRVAR(getwch_doc,
223"getwch() -> Unicode key character\n\
224\n\
225Wide char variant of getch(), returning a Unicode value.");
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000226#endif
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000227
228static PyObject *
Tim Peters5fa0bd62000-12-12 01:58:56 +0000229msvcrt_getche(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000230{
231 int ch;
232 char s[1];
233
234 if (!PyArg_ParseTuple(args, ":getche"))
235 return NULL;
236
Guido van Rossume4e021b1998-05-29 01:27:07 +0000237 Py_BEGIN_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000238 ch = _getche();
Guido van Rossume4e021b1998-05-29 01:27:07 +0000239 Py_END_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000240 s[0] = ch;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000241 return PyString_FromStringAndSize(s, 1);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000242}
243
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000244PyDoc_STRVAR(getche_doc,
245"getche() -> key character\n\
246\n\
247Similar to getch(), but the keypress will be echoed if it represents\n\
248a printable character.");
249
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000250#ifdef _WCONIO_DEFINED
Tim Peters5fa0bd62000-12-12 01:58:56 +0000251static PyObject *
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000252msvcrt_getwche(PyObject *self, PyObject *args)
253{
254 Py_UNICODE ch;
255 Py_UNICODE s[1];
256
257 if (!PyArg_ParseTuple(args, ":getwche"))
258 return NULL;
259
260 Py_BEGIN_ALLOW_THREADS
261 ch = _getwche();
262 Py_END_ALLOW_THREADS
263 s[0] = ch;
264 return PyUnicode_FromUnicode(s, 1);
265}
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000266
267PyDoc_STRVAR(getwche_doc,
268"getwche() -> Unicode key character\n\
269\n\
270Wide char variant of getche(), returning a Unicode value.");
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000271#endif
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000272
273static PyObject *
Tim Peters5fa0bd62000-12-12 01:58:56 +0000274msvcrt_putch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000275{
276 char ch;
277
278 if (!PyArg_ParseTuple(args, "c:putch", &ch))
279 return NULL;
280
281 _putch(ch);
282 Py_INCREF(Py_None);
283 return Py_None;
284}
285
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000286PyDoc_STRVAR(putch_doc,
287"putch(char) -> None\n\
288\n\
289Print the character char to the console without buffering.");
290
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000291#ifdef _WCONIO_DEFINED
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000292static PyObject *
293msvcrt_putwch(PyObject *self, PyObject *args)
294{
295 Py_UNICODE *ch;
296 int size;
297
298 if (!PyArg_ParseTuple(args, "u#:putwch", &ch, &size))
299 return NULL;
300
Christian Heimes61927fc2007-12-10 15:39:09 +0000301 if (size == 0) {
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000302 PyErr_SetString(PyExc_ValueError,
Christian Heimes61927fc2007-12-10 15:39:09 +0000303 "Expected unicode string of length 1");
304 return NULL;
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000305 }
Christian Heimes61927fc2007-12-10 15:39:09 +0000306 _putwch(*ch);
307 Py_RETURN_NONE;
308
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000309}
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000310
311PyDoc_STRVAR(putwch_doc,
312"putwch(unicode_char) -> None\n\
313\n\
314Wide char variant of putch(), accepting a Unicode value.");
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000315#endif
Christian Heimes7c7f6af2007-12-10 15:12:41 +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{
320 char ch;
321
322 if (!PyArg_ParseTuple(args, "c:ungetch", &ch))
323 return NULL;
324
Guido van Rossum6543e881999-02-16 19:40:02 +0000325 if (_ungetch(ch) == EOF)
326 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000327 Py_INCREF(Py_None);
328 return Py_None;
329}
330
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000331PyDoc_STRVAR(ungetch_doc,
332"ungetch(char) -> None\n\
333\n\
334Cause the character char to be \"pushed back\" into the console buffer;\n\
335it will be the next character read by getch() or getche().");
336
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000337#ifdef _WCONIO_DEFINED
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000338static PyObject *
339msvcrt_ungetwch(PyObject *self, PyObject *args)
340{
341 Py_UNICODE ch;
342
343 if (!PyArg_ParseTuple(args, "u:ungetwch", &ch))
344 return NULL;
345
346 if (_ungetch(ch) == EOF)
347 return PyErr_SetFromErrno(PyExc_IOError);
348 Py_INCREF(Py_None);
349 return Py_None;
350}
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000351
352PyDoc_STRVAR(ungetwch_doc,
353"ungetwch(unicode_char) -> None\n\
354\n\
355Wide char variant of ungetch(), accepting a Unicode value.");
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000356#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000357
Tim Peters5fa0bd62000-12-12 01:58:56 +0000358static void
359insertint(PyObject *d, char *name, int value)
360{
361 PyObject *v = PyInt_FromLong((long) value);
362 if (v == NULL) {
363 /* Don't bother reporting this error */
364 PyErr_Clear();
365 }
366 else {
367 PyDict_SetItemString(d, name, v);
368 Py_DECREF(v);
369 }
370}
371
372
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000373/* List of functions exported by this module */
374static struct PyMethodDef msvcrt_functions[] = {
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000375 {"heapmin", msvcrt_heapmin, METH_VARARGS, heapmin_doc},
376 {"locking", msvcrt_locking, METH_VARARGS, locking_doc},
377 {"setmode", msvcrt_setmode, METH_VARARGS, setmode_doc},
378 {"open_osfhandle", msvcrt_open_osfhandle, METH_VARARGS, open_osfhandle_doc},
379 {"get_osfhandle", msvcrt_get_osfhandle, METH_VARARGS, get_osfhandle_doc},
380 {"kbhit", msvcrt_kbhit, METH_VARARGS, kbhit_doc},
381 {"getch", msvcrt_getch, METH_VARARGS, getch_doc},
382 {"getche", msvcrt_getche, METH_VARARGS, getche_doc},
383 {"putch", msvcrt_putch, METH_VARARGS, putch_doc},
384 {"ungetch", msvcrt_ungetch, METH_VARARGS, ungetch_doc},
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000385#ifdef _WCONIO_DEFINED
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000386 {"getwch", msvcrt_getwch, METH_VARARGS, getwch_doc},
387 {"getwche", msvcrt_getwche, METH_VARARGS, getwche_doc},
388 {"putwch", msvcrt_putwch, METH_VARARGS, putwch_doc},
389 {"ungetwch", msvcrt_ungetwch, METH_VARARGS, ungetwch_doc},
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000390#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000391 {NULL, NULL}
392};
393
Thomas Hellera18331d2004-07-28 20:02:52 +0000394PyMODINIT_FUNC
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000395initmsvcrt(void)
396{
Martin v. Löwisbcb017f2008-11-30 19:28:27 +0000397 int st;
Tim Peters2188bf02006-01-19 15:21:30 +0000398 PyObject *d;
Tim Peters5fa0bd62000-12-12 01:58:56 +0000399 PyObject *m = Py_InitModule("msvcrt", msvcrt_functions);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000400 if (m == NULL)
401 return;
Tim Peters2188bf02006-01-19 15:21:30 +0000402 d = PyModule_GetDict(m);
Tim Peters5fa0bd62000-12-12 01:58:56 +0000403
404 /* constants for the locking() function's mode argument */
405 insertint(d, "LK_LOCK", _LK_LOCK);
406 insertint(d, "LK_NBLCK", _LK_NBLCK);
407 insertint(d, "LK_NBRLCK", _LK_NBRLCK);
408 insertint(d, "LK_RLCK", _LK_RLCK);
409 insertint(d, "LK_UNLCK", _LK_UNLCK);
Martin v. Löwisbcb017f2008-11-30 19:28:27 +0000410
411 /* constants for the crt versions */
412#ifdef _VC_ASSEMBLY_PUBLICKEYTOKEN
413 st = PyModule_AddStringConstant(m, "VC_ASSEMBLY_PUBLICKEYTOKEN",
414 _VC_ASSEMBLY_PUBLICKEYTOKEN);
415 if (st < 0)return;
416#endif
417#ifdef _CRT_ASSEMBLY_VERSION
418 st = PyModule_AddStringConstant(m, "CRT_ASSEMBLY_VERSION",
419 _CRT_ASSEMBLY_VERSION);
420 if (st < 0)return;
421#endif
422#ifdef __LIBRARIES_ASSEMBLY_NAME_PREFIX
423 st = PyModule_AddStringConstant(m, "LIBRARIES_ASSEMBLY_NAME_PREFIX",
424 __LIBRARIES_ASSEMBLY_NAME_PREFIX);
425 if (st < 0)return;
426#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000427}