PageRenderTime 655ms CodeModel.GetById 234ms app.highlight 102ms RepoModel.GetById 241ms app.codeStats 0ms

/PC/msvcrtmodule.c

http://unladen-swallow.googlecode.com/
C | 337 lines | 251 code | 55 blank | 31 comment | 38 complexity | 63dbd9364cbb94afd21cf99e696c77fc MD5 | raw file
  1/*********************************************************
  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
 12	This may only work on NT or 95...
 13
 14	Author: Mark Hammond and Guido van Rossum.
 15	Maintenance: Guido van Rossum.
 16
 17***********************************************************/
 18
 19#include "Python.h"
 20#include "malloc.h"
 21#include <io.h>
 22#include <conio.h>
 23#include <sys/locking.h>
 24
 25#ifdef _MSC_VER
 26#if _MSC_VER >= 1500
 27#include <crtassem.h>
 28#endif
 29#endif
 30
 31// 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.)
 33static PyObject *
 34msvcrt_heapmin(PyObject *self, PyObject *args)
 35{
 36	if (!PyArg_ParseTuple(args, ":heapmin"))
 37		return NULL;
 38
 39	if (_heapmin() != 0)
 40		return PyErr_SetFromErrno(PyExc_IOError);
 41
 42	Py_INCREF(Py_None);
 43	return Py_None;
 44}
 45
 46// Perform locking operations on a C runtime file descriptor.
 47static PyObject *
 48msvcrt_locking(PyObject *self, PyObject *args)
 49{
 50	int fd;
 51	int mode;
 52	long nbytes;
 53	int err;
 54
 55	if (!PyArg_ParseTuple(args, "iil:locking", &fd, &mode, &nbytes))
 56		return NULL;
 57
 58	Py_BEGIN_ALLOW_THREADS
 59	err = _locking(fd, mode, nbytes);
 60	Py_END_ALLOW_THREADS
 61	if (err != 0)
 62		return PyErr_SetFromErrno(PyExc_IOError);
 63
 64	Py_INCREF(Py_None);
 65	return Py_None;
 66}
 67
 68// Set the file translation mode for a C runtime file descriptor.
 69static PyObject *
 70msvcrt_setmode(PyObject *self, PyObject *args)
 71{
 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.
 85static PyObject *
 86msvcrt_open_osfhandle(PyObject *self, PyObject *args)
 87{
 88	long handle;
 89	int flags;
 90	int fd;
 91
 92	if (!PyArg_ParseTuple(args, "li:open_osfhandle", &handle, &flags))
 93		return NULL;
 94
 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.
103static PyObject *
104msvcrt_get_osfhandle(PyObject *self, PyObject *args)
105{
106	int fd;
107	Py_intptr_t handle;
108
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
116	/* 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);
120}
121
122/* Console I/O */
123
124static PyObject *
125msvcrt_kbhit(PyObject *self, PyObject *args)
126{
127	int ok;
128
129	if (!PyArg_ParseTuple(args, ":kbhit"))
130		return NULL;
131
132	ok = _kbhit();
133	return PyInt_FromLong(ok);
134}
135
136static PyObject *
137msvcrt_getch(PyObject *self, PyObject *args)
138{
139	int ch;
140	char s[1];
141
142	if (!PyArg_ParseTuple(args, ":getch"))
143		return NULL;
144
145	Py_BEGIN_ALLOW_THREADS
146	ch = _getch();
147	Py_END_ALLOW_THREADS
148	s[0] = ch;
149	return PyString_FromStringAndSize(s, 1);
150}
151
152#ifdef _WCONIO_DEFINED
153static PyObject *
154msvcrt_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}
168#endif
169
170static PyObject *
171msvcrt_getche(PyObject *self, PyObject *args)
172{
173	int ch;
174	char s[1];
175
176	if (!PyArg_ParseTuple(args, ":getche"))
177		return NULL;
178
179	Py_BEGIN_ALLOW_THREADS
180	ch = _getche();
181	Py_END_ALLOW_THREADS
182	s[0] = ch;
183	return PyString_FromStringAndSize(s, 1);
184}
185
186#ifdef _WCONIO_DEFINED
187static PyObject *
188msvcrt_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}
202#endif
203
204static PyObject *
205msvcrt_putch(PyObject *self, PyObject *args)
206{
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
217#ifdef _WCONIO_DEFINED
218static 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
227	if (size == 0) {
228		PyErr_SetString(PyExc_ValueError,
229			"Expected unicode string of length 1");
230		return NULL;
231	}
232	_putwch(*ch);
233	Py_RETURN_NONE;
234
235}
236#endif
237
238static PyObject *
239msvcrt_ungetch(PyObject *self, PyObject *args)
240{
241	char ch;
242
243	if (!PyArg_ParseTuple(args, "c:ungetch", &ch))
244		return NULL;
245
246	if (_ungetch(ch) == EOF)
247		return PyErr_SetFromErrno(PyExc_IOError);
248	Py_INCREF(Py_None);
249	return Py_None;
250}
251
252#ifdef _WCONIO_DEFINED
253static 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}
266#endif
267
268static 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
283/* List of functions exported by this module */
284static struct PyMethodDef msvcrt_functions[] = {
285	{"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},
295#ifdef _WCONIO_DEFINED
296	{"getwch",		msvcrt_getwch, METH_VARARGS},
297	{"getwche",		msvcrt_getwche, METH_VARARGS},
298	{"putwch",		msvcrt_putwch, METH_VARARGS},
299	{"ungetwch",		msvcrt_ungetwch, METH_VARARGS},
300#endif
301	{NULL,			NULL}
302};
303
304PyMODINIT_FUNC
305initmsvcrt(void)
306{
307	int st;
308	PyObject *d;
309	PyObject *m = Py_InitModule("msvcrt", msvcrt_functions);
310	if (m == NULL)
311		return;
312	d = PyModule_GetDict(m);
313
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);
320
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
337}