blob: 24e0cd521240b7a2d6ed3fdb38d66e2fb6892123 [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\
50to the operating system. This only works on Windows NT. On failure,\n\
51this raises IOError.");
52
Guido van Rossum407a22d1997-08-13 19:57:53 +000053// Perform locking operations on a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000054static PyObject *
55msvcrt_locking(PyObject *self, PyObject *args)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000056{
Guido van Rossum407a22d1997-08-13 19:57:53 +000057 int fd;
58 int mode;
59 long nbytes;
Guido van Rossume4e021b1998-05-29 01:27:07 +000060 int err;
Guido van Rossum407a22d1997-08-13 19:57:53 +000061
62 if (!PyArg_ParseTuple(args, "iil:locking", &fd, &mode, &nbytes))
Guido van Rossum29c1ea51997-08-07 00:11:34 +000063 return NULL;
64
Guido van Rossume4e021b1998-05-29 01:27:07 +000065 Py_BEGIN_ALLOW_THREADS
66 err = _locking(fd, mode, nbytes);
67 Py_END_ALLOW_THREADS
68 if (err != 0)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000069 return PyErr_SetFromErrno(PyExc_IOError);
70
Guido van Rossum407a22d1997-08-13 19:57:53 +000071 Py_INCREF(Py_None);
72 return Py_None;
Guido van Rossum29c1ea51997-08-07 00:11:34 +000073}
Guido van Rossum407a22d1997-08-13 19:57:53 +000074
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +000075PyDoc_STRVAR(locking_doc,
76"locking(fd, mode, nbytes) -> None\n\
77\n\
78Lock part of a file based on file descriptor fd from the C runtime.\n\
79Raises IOError on failure. The locked region of the file extends from\n\
80the current file position for nbytes bytes, and may continue beyond\n\
81the end of the file. mode must be one of the LK_* constants listed\n\
82below. Multiple regions in a file may be locked at the same time, but\n\
83may not overlap. Adjacent regions are not merged; they must be unlocked\n\
84individually.");
85
Guido van Rossum407a22d1997-08-13 19:57:53 +000086// Set the file translation mode for a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000087static PyObject *
88msvcrt_setmode(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +000089{
90 int fd;
91 int flags;
92 if (!PyArg_ParseTuple(args,"ii:setmode", &fd, &flags))
93 return NULL;
94
95 flags = _setmode(fd, flags);
96 if (flags == -1)
97 return PyErr_SetFromErrno(PyExc_IOError);
98
99 return PyInt_FromLong(flags);
100}
101
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000102PyDoc_STRVAR(setmode_doc,
103"setmode(fd, mode) -> Previous mode\n\
104\n\
105Set the line-end translation mode for the file descriptor fd. To set\n\
106it to text mode, flags should be os.O_TEXT; for binary, it should be\n\
107os.O_BINARY.");
108
Guido van Rossum407a22d1997-08-13 19:57:53 +0000109// Convert an OS file handle to a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +0000110static PyObject *
111msvcrt_open_osfhandle(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000112{
113 long handle;
114 int flags;
115 int fd;
116
117 if (!PyArg_ParseTuple(args, "li:open_osfhandle", &handle, &flags))
Guido van Rossume4e021b1998-05-29 01:27:07 +0000118 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000119
120 fd = _open_osfhandle(handle, flags);
121 if (fd == -1)
122 return PyErr_SetFromErrno(PyExc_IOError);
123
124 return PyInt_FromLong(fd);
125}
126
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000127PyDoc_STRVAR(open_osfhandle_doc,
128"open_osfhandle(handle, flags) -> file descriptor\n\
129\n\
130Create a C runtime file descriptor from the file handle handle. The\n\
131flags parameter should be a bitwise OR of os.O_APPEND, os.O_RDONLY,\n\
132and os.O_TEXT. The returned file descriptor may be used as a parameter\n\
133to os.fdopen() to create a file object.");
134
Guido van Rossum407a22d1997-08-13 19:57:53 +0000135// Convert a C runtime file descriptor to an OS file handle.
Tim Peters5fa0bd62000-12-12 01:58:56 +0000136static PyObject *
137msvcrt_get_osfhandle(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000138{
139 int fd;
Tim Peters79248aa2001-08-29 21:37:10 +0000140 Py_intptr_t handle;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000141
142 if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd))
143 return NULL;
144
145 handle = _get_osfhandle(fd);
146 if (handle == -1)
147 return PyErr_SetFromErrno(PyExc_IOError);
148
Fred Drake25e17262000-06-30 17:48:51 +0000149 /* technically 'handle' is not a pointer, but a integer as
150 large as a pointer, Python's *VoidPtr interface is the
151 most appropriate here */
152 return PyLong_FromVoidPtr((void*)handle);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000153}
154
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000155PyDoc_STRVAR(get_osfhandle_doc,
156"get_osfhandle(fd) -> file handle\n\
157\n\
158Return the file handle for the file descriptor fd. Raises IOError\n\
159if fd is not recognized.");
160
Guido van Rossum407a22d1997-08-13 19:57:53 +0000161/* Console I/O */
Guido van Rossum407a22d1997-08-13 19:57:53 +0000162
Tim Peters5fa0bd62000-12-12 01:58:56 +0000163static PyObject *
164msvcrt_kbhit(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000165{
166 int ok;
167
168 if (!PyArg_ParseTuple(args, ":kbhit"))
169 return NULL;
170
171 ok = _kbhit();
172 return PyInt_FromLong(ok);
173}
174
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000175PyDoc_STRVAR(kbhit_doc,
176"kbhit() -> bool\n\
177\n\
178Return true if a keypress is waiting to be read.");
179
Tim Peters5fa0bd62000-12-12 01:58:56 +0000180static PyObject *
181msvcrt_getch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000182{
183 int ch;
184 char s[1];
185
186 if (!PyArg_ParseTuple(args, ":getch"))
187 return NULL;
188
Guido van Rossume4e021b1998-05-29 01:27:07 +0000189 Py_BEGIN_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000190 ch = _getch();
Guido van Rossume4e021b1998-05-29 01:27:07 +0000191 Py_END_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000192 s[0] = ch;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000193 return PyString_FromStringAndSize(s, 1);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000194}
195
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000196PyDoc_STRVAR(getch_doc,
197"getch() -> key character\n\
198\n\
199Read a keypress and return the resulting character. Nothing is echoed to\n\
200the console. This call will block if a keypress is not already\n\
201available, but will not wait for Enter to be pressed. If the pressed key\n\
202was a special function key, this will return '\\000' or '\\xe0'; the next\n\
203call will return the keycode. The Control-C keypress cannot be read with\n\
204this function.");
205
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000206#ifdef _WCONIO_DEFINED
Tim Peters5fa0bd62000-12-12 01:58:56 +0000207static PyObject *
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000208msvcrt_getwch(PyObject *self, PyObject *args)
209{
210 Py_UNICODE ch;
211 Py_UNICODE u[1];
212
213 if (!PyArg_ParseTuple(args, ":getwch"))
214 return NULL;
215
216 Py_BEGIN_ALLOW_THREADS
217 ch = _getwch();
218 Py_END_ALLOW_THREADS
219 u[0] = ch;
220 return PyUnicode_FromUnicode(u, 1);
221}
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000222
223PyDoc_STRVAR(getwch_doc,
224"getwch() -> Unicode key character\n\
225\n\
226Wide char variant of getch(), returning a Unicode value.");
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000227#endif
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000228
229static PyObject *
Tim Peters5fa0bd62000-12-12 01:58:56 +0000230msvcrt_getche(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000231{
232 int ch;
233 char s[1];
234
235 if (!PyArg_ParseTuple(args, ":getche"))
236 return NULL;
237
Guido van Rossume4e021b1998-05-29 01:27:07 +0000238 Py_BEGIN_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000239 ch = _getche();
Guido van Rossume4e021b1998-05-29 01:27:07 +0000240 Py_END_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000241 s[0] = ch;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000242 return PyString_FromStringAndSize(s, 1);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000243}
244
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000245PyDoc_STRVAR(getche_doc,
246"getche() -> key character\n\
247\n\
248Similar to getch(), but the keypress will be echoed if it represents\n\
249a printable character.");
250
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000251#ifdef _WCONIO_DEFINED
Tim Peters5fa0bd62000-12-12 01:58:56 +0000252static PyObject *
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000253msvcrt_getwche(PyObject *self, PyObject *args)
254{
255 Py_UNICODE ch;
256 Py_UNICODE s[1];
257
258 if (!PyArg_ParseTuple(args, ":getwche"))
259 return NULL;
260
261 Py_BEGIN_ALLOW_THREADS
262 ch = _getwche();
263 Py_END_ALLOW_THREADS
264 s[0] = ch;
265 return PyUnicode_FromUnicode(s, 1);
266}
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000267
268PyDoc_STRVAR(getwche_doc,
269"getwche() -> Unicode key character\n\
270\n\
271Wide char variant of getche(), returning a Unicode value.");
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000272#endif
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000273
274static PyObject *
Tim Peters5fa0bd62000-12-12 01:58:56 +0000275msvcrt_putch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000276{
277 char ch;
278
279 if (!PyArg_ParseTuple(args, "c:putch", &ch))
280 return NULL;
281
282 _putch(ch);
283 Py_INCREF(Py_None);
284 return Py_None;
285}
286
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000287PyDoc_STRVAR(putch_doc,
288"putch(char) -> None\n\
289\n\
290Print the character char to the console without buffering.");
291
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000292#ifdef _WCONIO_DEFINED
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000293static PyObject *
294msvcrt_putwch(PyObject *self, PyObject *args)
295{
296 Py_UNICODE *ch;
297 int size;
298
299 if (!PyArg_ParseTuple(args, "u#:putwch", &ch, &size))
300 return NULL;
301
Christian Heimes61927fc2007-12-10 15:39:09 +0000302 if (size == 0) {
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000303 PyErr_SetString(PyExc_ValueError,
Christian Heimes61927fc2007-12-10 15:39:09 +0000304 "Expected unicode string of length 1");
305 return NULL;
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000306 }
Christian Heimes61927fc2007-12-10 15:39:09 +0000307 _putwch(*ch);
308 Py_RETURN_NONE;
309
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000310}
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000311
312PyDoc_STRVAR(putwch_doc,
313"putwch(unicode_char) -> None\n\
314\n\
315Wide char variant of putch(), accepting a Unicode value.");
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000316#endif
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000317
Tim Peters5fa0bd62000-12-12 01:58:56 +0000318static PyObject *
319msvcrt_ungetch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000320{
321 char ch;
322
323 if (!PyArg_ParseTuple(args, "c:ungetch", &ch))
324 return NULL;
325
Guido van Rossum6543e881999-02-16 19:40:02 +0000326 if (_ungetch(ch) == EOF)
327 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000328 Py_INCREF(Py_None);
329 return Py_None;
330}
331
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000332PyDoc_STRVAR(ungetch_doc,
333"ungetch(char) -> None\n\
334\n\
335Cause the character char to be \"pushed back\" into the console buffer;\n\
336it will be the next character read by getch() or getche().");
337
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000338#ifdef _WCONIO_DEFINED
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000339static PyObject *
340msvcrt_ungetwch(PyObject *self, PyObject *args)
341{
342 Py_UNICODE ch;
343
344 if (!PyArg_ParseTuple(args, "u:ungetwch", &ch))
345 return NULL;
346
347 if (_ungetch(ch) == EOF)
348 return PyErr_SetFromErrno(PyExc_IOError);
349 Py_INCREF(Py_None);
350 return Py_None;
351}
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000352
353PyDoc_STRVAR(ungetwch_doc,
354"ungetwch(unicode_char) -> None\n\
355\n\
356Wide char variant of ungetch(), accepting a Unicode value.");
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000357#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000358
Tim Peters5fa0bd62000-12-12 01:58:56 +0000359static void
360insertint(PyObject *d, char *name, int value)
361{
362 PyObject *v = PyInt_FromLong((long) value);
363 if (v == NULL) {
364 /* Don't bother reporting this error */
365 PyErr_Clear();
366 }
367 else {
368 PyDict_SetItemString(d, name, v);
369 Py_DECREF(v);
370 }
371}
372
373
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000374/* List of functions exported by this module */
375static struct PyMethodDef msvcrt_functions[] = {
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000376 {"heapmin", msvcrt_heapmin, METH_VARARGS, heapmin_doc},
377 {"locking", msvcrt_locking, METH_VARARGS, locking_doc},
378 {"setmode", msvcrt_setmode, METH_VARARGS, setmode_doc},
379 {"open_osfhandle", msvcrt_open_osfhandle, METH_VARARGS, open_osfhandle_doc},
380 {"get_osfhandle", msvcrt_get_osfhandle, METH_VARARGS, get_osfhandle_doc},
381 {"kbhit", msvcrt_kbhit, METH_VARARGS, kbhit_doc},
382 {"getch", msvcrt_getch, METH_VARARGS, getch_doc},
383 {"getche", msvcrt_getche, METH_VARARGS, getche_doc},
384 {"putch", msvcrt_putch, METH_VARARGS, putch_doc},
385 {"ungetch", msvcrt_ungetch, METH_VARARGS, ungetch_doc},
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000386#ifdef _WCONIO_DEFINED
Amaury Forgeot d'Arcc8a2ce72009-12-29 23:06:17 +0000387 {"getwch", msvcrt_getwch, METH_VARARGS, getwch_doc},
388 {"getwche", msvcrt_getwche, METH_VARARGS, getwche_doc},
389 {"putwch", msvcrt_putwch, METH_VARARGS, putwch_doc},
390 {"ungetwch", msvcrt_ungetwch, METH_VARARGS, ungetwch_doc},
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000391#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000392 {NULL, NULL}
393};
394
Thomas Hellera18331d2004-07-28 20:02:52 +0000395PyMODINIT_FUNC
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000396initmsvcrt(void)
397{
Martin v. Löwisbcb017f2008-11-30 19:28:27 +0000398 int st;
Tim Peters2188bf02006-01-19 15:21:30 +0000399 PyObject *d;
Tim Peters5fa0bd62000-12-12 01:58:56 +0000400 PyObject *m = Py_InitModule("msvcrt", msvcrt_functions);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000401 if (m == NULL)
402 return;
Tim Peters2188bf02006-01-19 15:21:30 +0000403 d = PyModule_GetDict(m);
Tim Peters5fa0bd62000-12-12 01:58:56 +0000404
405 /* constants for the locking() function's mode argument */
406 insertint(d, "LK_LOCK", _LK_LOCK);
407 insertint(d, "LK_NBLCK", _LK_NBLCK);
408 insertint(d, "LK_NBRLCK", _LK_NBRLCK);
409 insertint(d, "LK_RLCK", _LK_RLCK);
410 insertint(d, "LK_UNLCK", _LK_UNLCK);
Martin v. Löwisbcb017f2008-11-30 19:28:27 +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;
417#endif
418#ifdef _CRT_ASSEMBLY_VERSION
419 st = PyModule_AddStringConstant(m, "CRT_ASSEMBLY_VERSION",
420 _CRT_ASSEMBLY_VERSION);
421 if (st < 0)return;
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;
427#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000428}