|
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.) |
|
33 static PyObject * |
|
34 msvcrt_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. |
|
47 static PyObject * |
|
48 msvcrt_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. |
|
69 static PyObject * |
|
70 msvcrt_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. |
|
85 static PyObject * |
|
86 msvcrt_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. |
|
103 static PyObject * |
|
104 msvcrt_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 |
|
124 static PyObject * |
|
125 msvcrt_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 |
|
136 static PyObject * |
|
137 msvcrt_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 |
|
153 static PyObject * |
|
154 msvcrt_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 |
|
170 static PyObject * |
|
171 msvcrt_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 |
|
187 static PyObject * |
|
188 msvcrt_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 |
|
204 static PyObject * |
|
205 msvcrt_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 |
|
218 static PyObject * |
|
219 msvcrt_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 |
|
238 static PyObject * |
|
239 msvcrt_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 |
|
253 static PyObject * |
|
254 msvcrt_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 |
|
268 static void |
|
269 insertint(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 */ |
|
284 static 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 |
|
304 PyMODINIT_FUNC |
|
305 initmsvcrt(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 } |