Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 407a22d

Browse files
committed
Made it real. Changed locking() to work with file descriptors instead
of Python file objects. Added open_osfhandle() (Mark had done some work for that), get_osfhandle(), setmode(), and the console I/O functions kbhit(), getch(), getche(), ungetch(), and putch().
1 parent 8f1b651 commit 407a22d

1 file changed

Lines changed: 134 additions & 44 deletions

File tree

PC/msvcrtmodule.c

Lines changed: 134 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,82 +9,172 @@
99
Only ever compiled with an MS compiler, so no attempt
1010
has been made to avoid MS language extensions, etc...
1111
12+
This may only work on NT or 95...
13+
14+
Author: Mark Hammond and Guido van Rossum.
15+
Maintenance: Guido van Rossum.
16+
1217
***********************************************************/
18+
1319
#include "Python.h"
1420
#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)
1725
{
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"))
2327
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)
2730
return PyErr_SetFromErrno(PyExc_IOError);
31+
2832
Py_INCREF(Py_None);
2933
return Py_None;
3034
}
3135

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)
3538
{
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))
3744
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+
4049
Py_INCREF(Py_None);
4150
return Py_None;
4251
}
4352

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;
4660

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.
4969
static PyObject *msvcrt_open_osfhandle(PyObject *self, PyObject *args)
5070
{
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;
5772
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;
5889
long handle;
59-
if (!PyArg_ParseTuple(args,"Oi:open_osfhandle", &obHandle, &flags))
60-
return NULL;
6190

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))
6692
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)
7296
return PyErr_SetFromErrno(PyExc_IOError);
7397

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;
76135

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+
}
80140

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;
81151
}
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+
83165

84166
/* List of functions exported by this module */
85167
static struct PyMethodDef msvcrt_functions[] = {
168+
{"heapmin", msvcrt_heapmin, 1},
86169
{"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},
88178
{NULL, NULL}
89179
};
90180

0 commit comments

Comments
 (0)