This reverts r63675 based on the discussion in this thread:
[python.git] / PC / msvcrtmodule.c
blobe110ed8b091c4a13dcb93b7b1c49c272e8b1fcd9
1 /*********************************************************
3 msvcrtmodule.c
5 A Python interface to the Microsoft Visual C Runtime
6 Library, providing access to those non-portable, but
7 still useful routines.
9 Only ever compiled with an MS compiler, so no attempt
10 has been made to avoid MS language extensions, etc...
12 This may only work on NT or 95...
14 Author: Mark Hammond and Guido van Rossum.
15 Maintenance: Guido van Rossum.
17 ***********************************************************/
19 #include "Python.h"
20 #include "malloc.h"
21 #include <io.h>
22 #include <conio.h>
23 #include <sys/locking.h>
25 // 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.)
27 static PyObject *
28 msvcrt_heapmin(PyObject *self, PyObject *args)
30 if (!PyArg_ParseTuple(args, ":heapmin"))
31 return NULL;
33 if (_heapmin() != 0)
34 return PyErr_SetFromErrno(PyExc_IOError);
36 Py_INCREF(Py_None);
37 return Py_None;
40 // Perform locking operations on a C runtime file descriptor.
41 static PyObject *
42 msvcrt_locking(PyObject *self, PyObject *args)
44 int fd;
45 int mode;
46 long nbytes;
47 int err;
49 if (!PyArg_ParseTuple(args, "iil:locking", &fd, &mode, &nbytes))
50 return NULL;
52 Py_BEGIN_ALLOW_THREADS
53 err = _locking(fd, mode, nbytes);
54 Py_END_ALLOW_THREADS
55 if (err != 0)
56 return PyErr_SetFromErrno(PyExc_IOError);
58 Py_INCREF(Py_None);
59 return Py_None;
62 // Set the file translation mode for a C runtime file descriptor.
63 static PyObject *
64 msvcrt_setmode(PyObject *self, PyObject *args)
66 int fd;
67 int flags;
68 if (!PyArg_ParseTuple(args,"ii:setmode", &fd, &flags))
69 return NULL;
71 flags = _setmode(fd, flags);
72 if (flags == -1)
73 return PyErr_SetFromErrno(PyExc_IOError);
75 return PyInt_FromLong(flags);
78 // Convert an OS file handle to a C runtime file descriptor.
79 static PyObject *
80 msvcrt_open_osfhandle(PyObject *self, PyObject *args)
82 long handle;
83 int flags;
84 int fd;
86 if (!PyArg_ParseTuple(args, "li:open_osfhandle", &handle, &flags))
87 return NULL;
89 fd = _open_osfhandle(handle, flags);
90 if (fd == -1)
91 return PyErr_SetFromErrno(PyExc_IOError);
93 return PyInt_FromLong(fd);
96 // Convert a C runtime file descriptor to an OS file handle.
97 static PyObject *
98 msvcrt_get_osfhandle(PyObject *self, PyObject *args)
100 int fd;
101 Py_intptr_t handle;
103 if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd))
104 return NULL;
106 handle = _get_osfhandle(fd);
107 if (handle == -1)
108 return PyErr_SetFromErrno(PyExc_IOError);
110 /* 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);
116 /* Console I/O */
118 static PyObject *
119 msvcrt_kbhit(PyObject *self, PyObject *args)
121 int ok;
123 if (!PyArg_ParseTuple(args, ":kbhit"))
124 return NULL;
126 ok = _kbhit();
127 return PyInt_FromLong(ok);
130 static PyObject *
131 msvcrt_getch(PyObject *self, PyObject *args)
133 int ch;
134 char s[1];
136 if (!PyArg_ParseTuple(args, ":getch"))
137 return NULL;
139 Py_BEGIN_ALLOW_THREADS
140 ch = _getch();
141 Py_END_ALLOW_THREADS
142 s[0] = ch;
143 return PyString_FromStringAndSize(s, 1);
146 static PyObject *
147 msvcrt_getwch(PyObject *self, PyObject *args)
149 Py_UNICODE ch;
150 Py_UNICODE u[1];
152 if (!PyArg_ParseTuple(args, ":getwch"))
153 return NULL;
155 Py_BEGIN_ALLOW_THREADS
156 ch = _getwch();
157 Py_END_ALLOW_THREADS
158 u[0] = ch;
159 return PyUnicode_FromUnicode(u, 1);
162 static PyObject *
163 msvcrt_getche(PyObject *self, PyObject *args)
165 int ch;
166 char s[1];
168 if (!PyArg_ParseTuple(args, ":getche"))
169 return NULL;
171 Py_BEGIN_ALLOW_THREADS
172 ch = _getche();
173 Py_END_ALLOW_THREADS
174 s[0] = ch;
175 return PyString_FromStringAndSize(s, 1);
178 static PyObject *
179 msvcrt_getwche(PyObject *self, PyObject *args)
181 Py_UNICODE ch;
182 Py_UNICODE s[1];
184 if (!PyArg_ParseTuple(args, ":getwche"))
185 return NULL;
187 Py_BEGIN_ALLOW_THREADS
188 ch = _getwche();
189 Py_END_ALLOW_THREADS
190 s[0] = ch;
191 return PyUnicode_FromUnicode(s, 1);
194 static PyObject *
195 msvcrt_putch(PyObject *self, PyObject *args)
197 char ch;
199 if (!PyArg_ParseTuple(args, "c:putch", &ch))
200 return NULL;
202 _putch(ch);
203 Py_INCREF(Py_None);
204 return Py_None;
208 static PyObject *
209 msvcrt_putwch(PyObject *self, PyObject *args)
211 Py_UNICODE *ch;
212 int size;
214 if (!PyArg_ParseTuple(args, "u#:putwch", &ch, &size))
215 return NULL;
217 if (size == 0) {
218 PyErr_SetString(PyExc_ValueError,
219 "Expected unicode string of length 1");
220 return NULL;
222 _putwch(*ch);
223 Py_RETURN_NONE;
227 static PyObject *
228 msvcrt_ungetch(PyObject *self, PyObject *args)
230 char ch;
232 if (!PyArg_ParseTuple(args, "c:ungetch", &ch))
233 return NULL;
235 if (_ungetch(ch) == EOF)
236 return PyErr_SetFromErrno(PyExc_IOError);
237 Py_INCREF(Py_None);
238 return Py_None;
241 static PyObject *
242 msvcrt_ungetwch(PyObject *self, PyObject *args)
244 Py_UNICODE ch;
246 if (!PyArg_ParseTuple(args, "u:ungetwch", &ch))
247 return NULL;
249 if (_ungetch(ch) == EOF)
250 return PyErr_SetFromErrno(PyExc_IOError);
251 Py_INCREF(Py_None);
252 return Py_None;
255 static void
256 insertint(PyObject *d, char *name, int value)
258 PyObject *v = PyInt_FromLong((long) value);
259 if (v == NULL) {
260 /* Don't bother reporting this error */
261 PyErr_Clear();
263 else {
264 PyDict_SetItemString(d, name, v);
265 Py_DECREF(v);
270 /* List of functions exported by this module */
271 static struct PyMethodDef msvcrt_functions[] = {
272 {"heapmin", msvcrt_heapmin, METH_VARARGS},
273 {"locking", msvcrt_locking, METH_VARARGS},
274 {"setmode", msvcrt_setmode, METH_VARARGS},
275 {"open_osfhandle", msvcrt_open_osfhandle, METH_VARARGS},
276 {"get_osfhandle", msvcrt_get_osfhandle, METH_VARARGS},
277 {"kbhit", msvcrt_kbhit, METH_VARARGS},
278 {"getch", msvcrt_getch, METH_VARARGS},
279 {"getche", msvcrt_getche, METH_VARARGS},
280 {"putch", msvcrt_putch, METH_VARARGS},
281 {"ungetch", msvcrt_ungetch, METH_VARARGS},
282 {"getwch", msvcrt_getwch, METH_VARARGS},
283 {"getwche", msvcrt_getwche, METH_VARARGS},
284 {"putwch", msvcrt_putwch, METH_VARARGS},
285 {"ungetwch", msvcrt_ungetwch, METH_VARARGS},
287 {NULL, NULL}
290 PyMODINIT_FUNC
291 initmsvcrt(void)
293 PyObject *d;
294 PyObject *m = Py_InitModule("msvcrt", msvcrt_functions);
295 if (m == NULL)
296 return;
297 d = PyModule_GetDict(m);
299 /* constants for the locking() function's mode argument */
300 insertint(d, "LK_LOCK", _LK_LOCK);
301 insertint(d, "LK_NBLCK", _LK_NBLCK);
302 insertint(d, "LK_NBRLCK", _LK_NBRLCK);
303 insertint(d, "LK_RLCK", _LK_RLCK);
304 insertint(d, "LK_UNLCK", _LK_UNLCK);