blob: 95e369b42499f78bb30308992ea2fa5a3a4000f4 [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
Guido van Rossum407a22d1997-08-13 19:57:53 +000025// Force the malloc heap to clean itself up, and free unused blocks
26// back to the OS. (According to the docs, only works on NT.)
Tim Peters5fa0bd62000-12-12 01:58:56 +000027static PyObject *
28msvcrt_heapmin(PyObject *self, PyObject *args)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000029{
Guido van Rossum407a22d1997-08-13 19:57:53 +000030 if (!PyArg_ParseTuple(args, ":heapmin"))
Guido van Rossum29c1ea51997-08-07 00:11:34 +000031 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +000032
33 if (_heapmin() != 0)
34 return PyErr_SetFromErrno(PyExc_IOError);
35
Guido van Rossum29c1ea51997-08-07 00:11:34 +000036 Py_INCREF(Py_None);
37 return Py_None;
38}
39
Guido van Rossum407a22d1997-08-13 19:57:53 +000040// Perform locking operations on a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000041static PyObject *
42msvcrt_locking(PyObject *self, PyObject *args)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000043{
Guido van Rossum407a22d1997-08-13 19:57:53 +000044 int fd;
45 int mode;
46 long nbytes;
Guido van Rossume4e021b1998-05-29 01:27:07 +000047 int err;
Guido van Rossum407a22d1997-08-13 19:57:53 +000048
49 if (!PyArg_ParseTuple(args, "iil:locking", &fd, &mode, &nbytes))
Guido van Rossum29c1ea51997-08-07 00:11:34 +000050 return NULL;
51
Guido van Rossume4e021b1998-05-29 01:27:07 +000052 Py_BEGIN_ALLOW_THREADS
53 err = _locking(fd, mode, nbytes);
54 Py_END_ALLOW_THREADS
55 if (err != 0)
Guido van Rossum29c1ea51997-08-07 00:11:34 +000056 return PyErr_SetFromErrno(PyExc_IOError);
57
Guido van Rossum407a22d1997-08-13 19:57:53 +000058 Py_INCREF(Py_None);
59 return Py_None;
Guido van Rossum29c1ea51997-08-07 00:11:34 +000060}
Guido van Rossum407a22d1997-08-13 19:57:53 +000061
62// Set the file translation mode for a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000063static PyObject *
64msvcrt_setmode(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +000065{
66 int fd;
67 int flags;
68 if (!PyArg_ParseTuple(args,"ii:setmode", &fd, &flags))
69 return NULL;
70
71 flags = _setmode(fd, flags);
72 if (flags == -1)
73 return PyErr_SetFromErrno(PyExc_IOError);
74
75 return PyInt_FromLong(flags);
76}
77
78// Convert an OS file handle to a C runtime file descriptor.
Tim Peters5fa0bd62000-12-12 01:58:56 +000079static PyObject *
80msvcrt_open_osfhandle(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +000081{
82 long handle;
83 int flags;
84 int fd;
85
86 if (!PyArg_ParseTuple(args, "li:open_osfhandle", &handle, &flags))
Guido van Rossume4e021b1998-05-29 01:27:07 +000087 return NULL;
Guido van Rossum407a22d1997-08-13 19:57:53 +000088
89 fd = _open_osfhandle(handle, flags);
90 if (fd == -1)
91 return PyErr_SetFromErrno(PyExc_IOError);
92
93 return PyInt_FromLong(fd);
94}
95
96// Convert a C runtime file descriptor to an OS file handle.
Tim Peters5fa0bd62000-12-12 01:58:56 +000097static PyObject *
98msvcrt_get_osfhandle(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +000099{
100 int fd;
Tim Peters79248aa2001-08-29 21:37:10 +0000101 Py_intptr_t handle;
Guido van Rossum407a22d1997-08-13 19:57:53 +0000102
103 if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd))
104 return NULL;
105
106 handle = _get_osfhandle(fd);
107 if (handle == -1)
108 return PyErr_SetFromErrno(PyExc_IOError);
109
Fred Drake25e17262000-06-30 17:48:51 +0000110 /* technically 'handle' is not a pointer, but a integer as
111 large as a pointer, Python's *VoidPtr interface is the
112 most appropriate here */
113 return PyLong_FromVoidPtr((void*)handle);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000114}
115
116/* Console I/O */
Guido van Rossum407a22d1997-08-13 19:57:53 +0000117
Tim Peters5fa0bd62000-12-12 01:58:56 +0000118static PyObject *
119msvcrt_kbhit(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000120{
121 int ok;
122
123 if (!PyArg_ParseTuple(args, ":kbhit"))
124 return NULL;
125
126 ok = _kbhit();
127 return PyInt_FromLong(ok);
128}
129
Tim Peters5fa0bd62000-12-12 01:58:56 +0000130static PyObject *
131msvcrt_getch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000132{
133 int ch;
134 char s[1];
135
136 if (!PyArg_ParseTuple(args, ":getch"))
137 return NULL;
138
Guido van Rossume4e021b1998-05-29 01:27:07 +0000139 Py_BEGIN_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000140 ch = _getch();
Guido van Rossume4e021b1998-05-29 01:27:07 +0000141 Py_END_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000142 s[0] = ch;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000143 return PyString_FromStringAndSize(s, 1);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000144}
145
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000146#ifdef _WCONIO_DEFINED
Tim Peters5fa0bd62000-12-12 01:58:56 +0000147static PyObject *
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000148msvcrt_getwch(PyObject *self, PyObject *args)
149{
150 Py_UNICODE ch;
151 Py_UNICODE u[1];
152
153 if (!PyArg_ParseTuple(args, ":getwch"))
154 return NULL;
155
156 Py_BEGIN_ALLOW_THREADS
157 ch = _getwch();
158 Py_END_ALLOW_THREADS
159 u[0] = ch;
160 return PyUnicode_FromUnicode(u, 1);
161}
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000162#endif
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000163
164static PyObject *
Tim Peters5fa0bd62000-12-12 01:58:56 +0000165msvcrt_getche(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000166{
167 int ch;
168 char s[1];
169
170 if (!PyArg_ParseTuple(args, ":getche"))
171 return NULL;
172
Guido van Rossume4e021b1998-05-29 01:27:07 +0000173 Py_BEGIN_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000174 ch = _getche();
Guido van Rossume4e021b1998-05-29 01:27:07 +0000175 Py_END_ALLOW_THREADS
Guido van Rossum407a22d1997-08-13 19:57:53 +0000176 s[0] = ch;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000177 return PyString_FromStringAndSize(s, 1);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000178}
179
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000180#ifdef _WCONIO_DEFINED
Tim Peters5fa0bd62000-12-12 01:58:56 +0000181static PyObject *
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000182msvcrt_getwche(PyObject *self, PyObject *args)
183{
184 Py_UNICODE ch;
185 Py_UNICODE s[1];
186
187 if (!PyArg_ParseTuple(args, ":getwche"))
188 return NULL;
189
190 Py_BEGIN_ALLOW_THREADS
191 ch = _getwche();
192 Py_END_ALLOW_THREADS
193 s[0] = ch;
194 return PyUnicode_FromUnicode(s, 1);
195}
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000196#endif
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000197
198static PyObject *
Tim Peters5fa0bd62000-12-12 01:58:56 +0000199msvcrt_putch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000200{
201 char ch;
202
203 if (!PyArg_ParseTuple(args, "c:putch", &ch))
204 return NULL;
205
206 _putch(ch);
207 Py_INCREF(Py_None);
208 return Py_None;
209}
210
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000211#ifdef _WCONIO_DEFINED
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000212static PyObject *
213msvcrt_putwch(PyObject *self, PyObject *args)
214{
215 Py_UNICODE *ch;
216 int size;
217
218 if (!PyArg_ParseTuple(args, "u#:putwch", &ch, &size))
219 return NULL;
220
Christian Heimes61927fc2007-12-10 15:39:09 +0000221 if (size == 0) {
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000222 PyErr_SetString(PyExc_ValueError,
Christian Heimes61927fc2007-12-10 15:39:09 +0000223 "Expected unicode string of length 1");
224 return NULL;
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000225 }
Christian Heimes61927fc2007-12-10 15:39:09 +0000226 _putwch(*ch);
227 Py_RETURN_NONE;
228
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000229}
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000230#endif
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000231
Tim Peters5fa0bd62000-12-12 01:58:56 +0000232static PyObject *
233msvcrt_ungetch(PyObject *self, PyObject *args)
Guido van Rossum407a22d1997-08-13 19:57:53 +0000234{
235 char ch;
236
237 if (!PyArg_ParseTuple(args, "c:ungetch", &ch))
238 return NULL;
239
Guido van Rossum6543e881999-02-16 19:40:02 +0000240 if (_ungetch(ch) == EOF)
241 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum407a22d1997-08-13 19:57:53 +0000242 Py_INCREF(Py_None);
243 return Py_None;
244}
245
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000246#ifdef _WCONIO_DEFINED
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000247static PyObject *
248msvcrt_ungetwch(PyObject *self, PyObject *args)
249{
250 Py_UNICODE ch;
251
252 if (!PyArg_ParseTuple(args, "u:ungetwch", &ch))
253 return NULL;
254
255 if (_ungetch(ch) == EOF)
256 return PyErr_SetFromErrno(PyExc_IOError);
257 Py_INCREF(Py_None);
258 return Py_None;
259}
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000260#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000261
Tim Peters5fa0bd62000-12-12 01:58:56 +0000262static void
263insertint(PyObject *d, char *name, int value)
264{
265 PyObject *v = PyInt_FromLong((long) value);
266 if (v == NULL) {
267 /* Don't bother reporting this error */
268 PyErr_Clear();
269 }
270 else {
271 PyDict_SetItemString(d, name, v);
272 Py_DECREF(v);
273 }
274}
275
276
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000277/* List of functions exported by this module */
278static struct PyMethodDef msvcrt_functions[] = {
Neal Norwitz031829d2002-03-31 14:37:44 +0000279 {"heapmin", msvcrt_heapmin, METH_VARARGS},
280 {"locking", msvcrt_locking, METH_VARARGS},
281 {"setmode", msvcrt_setmode, METH_VARARGS},
282 {"open_osfhandle", msvcrt_open_osfhandle, METH_VARARGS},
283 {"get_osfhandle", msvcrt_get_osfhandle, METH_VARARGS},
284 {"kbhit", msvcrt_kbhit, METH_VARARGS},
285 {"getch", msvcrt_getch, METH_VARARGS},
286 {"getche", msvcrt_getche, METH_VARARGS},
287 {"putch", msvcrt_putch, METH_VARARGS},
288 {"ungetch", msvcrt_ungetch, METH_VARARGS},
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000289#ifdef _WCONIO_DEFINED
Christian Heimes7c7f6af2007-12-10 15:12:41 +0000290 {"getwch", msvcrt_getwch, METH_VARARGS},
291 {"getwche", msvcrt_getwche, METH_VARARGS},
292 {"putwch", msvcrt_putwch, METH_VARARGS},
293 {"ungetwch", msvcrt_ungetwch, METH_VARARGS},
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +0000294#endif
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000295 {NULL, NULL}
296};
297
Thomas Hellera18331d2004-07-28 20:02:52 +0000298PyMODINIT_FUNC
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000299initmsvcrt(void)
300{
Tim Peters2188bf02006-01-19 15:21:30 +0000301 PyObject *d;
Tim Peters5fa0bd62000-12-12 01:58:56 +0000302 PyObject *m = Py_InitModule("msvcrt", msvcrt_functions);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000303 if (m == NULL)
304 return;
Tim Peters2188bf02006-01-19 15:21:30 +0000305 d = PyModule_GetDict(m);
Tim Peters5fa0bd62000-12-12 01:58:56 +0000306
307 /* constants for the locking() function's mode argument */
308 insertint(d, "LK_LOCK", _LK_LOCK);
309 insertint(d, "LK_NBLCK", _LK_NBLCK);
310 insertint(d, "LK_NBRLCK", _LK_NBRLCK);
311 insertint(d, "LK_RLCK", _LK_RLCK);
312 insertint(d, "LK_UNLCK", _LK_UNLCK);
Guido van Rossum29c1ea51997-08-07 00:11:34 +0000313}