|
9 | 9 | Only ever compiled with an MS compiler, so no attempt |
10 | 10 | has been made to avoid MS language extensions, etc... |
11 | 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 | +
|
12 | 17 | ***********************************************************/ |
| 18 | + |
13 | 19 | #include "Python.h" |
14 | 20 | #include "malloc.h" |
15 | | -// Perform locking operations on a file. |
16 | | -static PyObject *msvcrt_locking(PyObject *self, PyObject *args) |
| 21 | + |
| 22 | +// Force the malloc heap to clean itself up, and free unused blocks |
| 23 | +// back to the OS. (According to the docs, only works on NT.) |
| 24 | +static PyObject *msvcrt_heapmin(PyObject *self, PyObject *args) |
17 | 25 | { |
18 | | - int mode; |
19 | | - long nBytes; |
20 | | - PyObject *obFile; |
21 | | - FILE *pFile; |
22 | | - if (!PyArg_ParseTuple(args,"O!il:locking", &obFile, PyFile_Type, &mode, &nBytes)) |
| 26 | + if (!PyArg_ParseTuple(args, ":heapmin")) |
23 | 27 | return NULL; |
24 | | - if (NULL==(pFile = PyFile_AsFile(obFile))) |
25 | | - return NULL; |
26 | | - if (0 != _locking(_fileno(pFile), mode, nBytes)) |
| 28 | + |
| 29 | + if (_heapmin() != 0) |
27 | 30 | return PyErr_SetFromErrno(PyExc_IOError); |
| 31 | + |
28 | 32 | Py_INCREF(Py_None); |
29 | 33 | return Py_None; |
30 | 34 | } |
31 | 35 |
|
32 | | -// Forces the malloc heap to clean itself up, and free unused blocks |
33 | | -// back to the OS. |
34 | | -static PyObject *msvcrt_heapmin(PyObject *self, PyObject *args) |
| 36 | +// Perform locking operations on a C runtime file descriptor. |
| 37 | +static PyObject *msvcrt_locking(PyObject *self, PyObject *args) |
35 | 38 | { |
36 | | - if (!PyArg_ParseTuple(args,":heapmin")) |
| 39 | + int fd; |
| 40 | + int mode; |
| 41 | + long nbytes; |
| 42 | + |
| 43 | + if (!PyArg_ParseTuple(args, "iil:locking", &fd, &mode, &nbytes)) |
37 | 44 | return NULL; |
38 | | - if (_heapmin()!=0) |
39 | | - return PyErr_SetFromErrno(PyExc_MemoryError); // Is this the correct error??? |
| 45 | + |
| 46 | + if (_locking(fd, mode, nbytes) != 0) |
| 47 | + return PyErr_SetFromErrno(PyExc_IOError); |
| 48 | + |
40 | 49 | Py_INCREF(Py_None); |
41 | 50 | return Py_None; |
42 | 51 | } |
43 | 52 |
|
44 | | -/******* |
45 | | -Left this out for now... |
| 53 | +// Set the file translation mode for a C runtime file descriptor. |
| 54 | +static PyObject *msvcrt_setmode(PyObject *self, PyObject *args) |
| 55 | +{ |
| 56 | + int fd; |
| 57 | + int flags; |
| 58 | + if (!PyArg_ParseTuple(args,"ii:setmode", &fd, &flags)) |
| 59 | + return NULL; |
46 | 60 |
|
47 | | -// Convert an OS file handle to a Python file object (yay!). |
48 | | -// This may only work on NT |
| 61 | + flags = _setmode(fd, flags); |
| 62 | + if (flags == -1) |
| 63 | + return PyErr_SetFromErrno(PyExc_IOError); |
| 64 | + |
| 65 | + return PyInt_FromLong(flags); |
| 66 | +} |
| 67 | + |
| 68 | +// Convert an OS file handle to a C runtime file descriptor. |
49 | 69 | static PyObject *msvcrt_open_osfhandle(PyObject *self, PyObject *args) |
50 | 70 | { |
51 | | - // Note that we get the underlying handle using the long |
52 | | - // "abstract" interface. This will allow either a native integer |
53 | | - // or else a Win32 extension PyHANDLE object, which implements an |
54 | | - // int() converter. |
55 | | - PyObject *obHandle; |
56 | | - PyObject *obInt; |
| 71 | + long handle; |
57 | 72 | int flags; |
| 73 | + int fd; |
| 74 | + |
| 75 | + if (!PyArg_ParseTuple(args, "li:open_osfhandle", &handle, &flags)) |
| 76 | + return PyErr_SetFromErrno(PyExc_IOError); |
| 77 | + |
| 78 | + fd = _open_osfhandle(handle, flags); |
| 79 | + if (fd == -1) |
| 80 | + return PyErr_SetFromErrno(PyExc_IOError); |
| 81 | + |
| 82 | + return PyInt_FromLong(fd); |
| 83 | +} |
| 84 | + |
| 85 | +// Convert a C runtime file descriptor to an OS file handle. |
| 86 | +static PyObject *msvcrt_get_osfhandle(PyObject *self, PyObject *args) |
| 87 | +{ |
| 88 | + int fd; |
58 | 89 | long handle; |
59 | | - if (!PyArg_ParseTuple(args,"Oi:open_osfhandle", &obHandle, &flags)) |
60 | | - return NULL; |
61 | 90 |
|
62 | | - if (NULL==(obInt = PyNumber_Int(obHandle))) { |
63 | | - PyErr_Clear(); |
64 | | - PyErr_SetString(PyExc_TypeError, "The handle param must be an integer, = |
65 | | -or an object able to be converted to an integer"); |
| 91 | + if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd)) |
66 | 92 | return NULL; |
67 | | - } |
68 | | - handle = PyInt_AsLong(obInt); |
69 | | - Py_DECREF(obInt); |
70 | | - rtHandle = _open_osfhandle(handle, flags); |
71 | | - if (rtHandle==-1) |
| 93 | + |
| 94 | + handle = _get_osfhandle(fd); |
| 95 | + if (handle == -1) |
72 | 96 | return PyErr_SetFromErrno(PyExc_IOError); |
73 | 97 |
|
74 | | - what mode? Should I just return here, and expose _fdopen |
75 | | - and setvbuf? |
| 98 | + return PyInt_FromLong(handle); |
| 99 | +} |
| 100 | + |
| 101 | +/* Console I/O */ |
| 102 | +#include <conio.h> |
| 103 | + |
| 104 | +static PyObject *msvcrt_kbhit(PyObject *self, PyObject *args) |
| 105 | +{ |
| 106 | + int ok; |
| 107 | + |
| 108 | + if (!PyArg_ParseTuple(args, ":kbhit")) |
| 109 | + return NULL; |
| 110 | + |
| 111 | + ok = _kbhit(); |
| 112 | + return PyInt_FromLong(ok); |
| 113 | +} |
| 114 | + |
| 115 | +static PyObject *msvcrt_getch(PyObject *self, PyObject *args) |
| 116 | +{ |
| 117 | + int ch; |
| 118 | + char s[1]; |
| 119 | + |
| 120 | + if (!PyArg_ParseTuple(args, ":getch")) |
| 121 | + return NULL; |
| 122 | + |
| 123 | + ch = _getch(); |
| 124 | + s[0] = ch; |
| 125 | + return PyString_FromStringAndSize(s, 1); |
| 126 | +} |
| 127 | + |
| 128 | +static PyObject *msvcrt_getche(PyObject *self, PyObject *args) |
| 129 | +{ |
| 130 | + int ch; |
| 131 | + char s[1]; |
| 132 | + |
| 133 | + if (!PyArg_ParseTuple(args, ":getche")) |
| 134 | + return NULL; |
76 | 135 |
|
77 | | - f1=_fdopen(fd1, "w"); |
78 | | - setvbuf(f1, NULL, _IONBF, 0); |
79 | | - f=PyFile_FromFile(f1, cmdstring, "w", fclose); |
| 136 | + ch = _getche(); |
| 137 | + s[0] = ch; |
| 138 | + return PyString_FromStringAndSize(s, 1); |
| 139 | +} |
80 | 140 |
|
| 141 | +static PyObject *msvcrt_putch(PyObject *self, PyObject *args) |
| 142 | +{ |
| 143 | + char ch; |
| 144 | + |
| 145 | + if (!PyArg_ParseTuple(args, "c:putch", &ch)) |
| 146 | + return NULL; |
| 147 | + |
| 148 | + _putch(ch); |
| 149 | + Py_INCREF(Py_None); |
| 150 | + return Py_None; |
81 | 151 | } |
82 | | -*****/ |
| 152 | + |
| 153 | +static PyObject *msvcrt_ungetch(PyObject *self, PyObject *args) |
| 154 | +{ |
| 155 | + char ch; |
| 156 | + |
| 157 | + if (!PyArg_ParseTuple(args, "c:ungetch", &ch)) |
| 158 | + return NULL; |
| 159 | + |
| 160 | + _ungetch(ch); |
| 161 | + Py_INCREF(Py_None); |
| 162 | + return Py_None; |
| 163 | +} |
| 164 | + |
83 | 165 |
|
84 | 166 | /* List of functions exported by this module */ |
85 | 167 | static struct PyMethodDef msvcrt_functions[] = { |
| 168 | + {"heapmin", msvcrt_heapmin, 1}, |
86 | 169 | {"locking", msvcrt_locking, 1}, |
87 | | - {"heapmin", msvcrt_heapmin, 1}, |
| 170 | + {"setmode", msvcrt_setmode, 1}, |
| 171 | + {"open_osfhandle", msvcrt_open_osfhandle, 1}, |
| 172 | + {"get_osfhandle", msvcrt_get_osfhandle, 1}, |
| 173 | + {"kbhit", msvcrt_kbhit, 1}, |
| 174 | + {"getch", msvcrt_getch, 1}, |
| 175 | + {"getche", msvcrt_getche, 1}, |
| 176 | + {"putch", msvcrt_putch, 1}, |
| 177 | + {"ungetch", msvcrt_ungetch, 1}, |
88 | 178 | {NULL, NULL} |
89 | 179 | }; |
90 | 180 |
|
|
0 commit comments