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().
This commit is contained in:
Guido van Rossum 1997-08-13 19:57:53 +00:00
parent 8f1b651980
commit 407a22d2ce

View file

@ -9,82 +9,172 @@
Only ever compiled with an MS compiler, so no attempt
has been made to avoid MS language extensions, etc...
This may only work on NT or 95...
Author: Mark Hammond and Guido van Rossum.
Maintenance: Guido van Rossum.
***********************************************************/
#include "Python.h"
#include "malloc.h"
// Perform locking operations on a file.
static PyObject *msvcrt_locking(PyObject *self, PyObject *args)
{
int mode;
long nBytes;
PyObject *obFile;
FILE *pFile;
if (!PyArg_ParseTuple(args,"O!il:locking", &obFile, PyFile_Type, &mode, &nBytes))
return NULL;
if (NULL==(pFile = PyFile_AsFile(obFile)))
return NULL;
if (0 != _locking(_fileno(pFile), mode, nBytes))
return PyErr_SetFromErrno(PyExc_IOError);
Py_INCREF(Py_None);
return Py_None;
}
// Forces the malloc heap to clean itself up, and free unused blocks
// back to the OS.
// Force the malloc heap to clean itself up, and free unused blocks
// back to the OS. (According to the docs, only works on NT.)
static PyObject *msvcrt_heapmin(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args,":heapmin"))
if (!PyArg_ParseTuple(args, ":heapmin"))
return NULL;
if (_heapmin()!=0)
return PyErr_SetFromErrno(PyExc_MemoryError); // Is this the correct error???
if (_heapmin() != 0)
return PyErr_SetFromErrno(PyExc_IOError);
Py_INCREF(Py_None);
return Py_None;
}
/*******
Left this out for now...
// Convert an OS file handle to a Python file object (yay!).
// This may only work on NT
static PyObject *msvcrt_open_osfhandle(PyObject *self, PyObject *args)
// Perform locking operations on a C runtime file descriptor.
static PyObject *msvcrt_locking(PyObject *self, PyObject *args)
{
// Note that we get the underlying handle using the long
// "abstract" interface. This will allow either a native integer
// or else a Win32 extension PyHANDLE object, which implements an
// int() converter.
PyObject *obHandle;
PyObject *obInt;
int flags;
long handle;
if (!PyArg_ParseTuple(args,"Oi:open_osfhandle", &obHandle, &flags))
int fd;
int mode;
long nbytes;
if (!PyArg_ParseTuple(args, "iil:locking", &fd, &mode, &nbytes))
return NULL;
if (NULL==(obInt = PyNumber_Int(obHandle))) {
PyErr_Clear();
PyErr_SetString(PyExc_TypeError, "The handle param must be an integer, =
or an object able to be converted to an integer");
return NULL;
}
handle = PyInt_AsLong(obInt);
Py_DECREF(obInt);
rtHandle = _open_osfhandle(handle, flags);
if (rtHandle==-1)
if (_locking(fd, mode, nbytes) != 0)
return PyErr_SetFromErrno(PyExc_IOError);
what mode? Should I just return here, and expose _fdopen
and setvbuf?
f1=_fdopen(fd1, "w");
setvbuf(f1, NULL, _IONBF, 0);
f=PyFile_FromFile(f1, cmdstring, "w", fclose);
Py_INCREF(Py_None);
return Py_None;
}
*****/
// Set the file translation mode for a C runtime file descriptor.
static PyObject *msvcrt_setmode(PyObject *self, PyObject *args)
{
int fd;
int flags;
if (!PyArg_ParseTuple(args,"ii:setmode", &fd, &flags))
return NULL;
flags = _setmode(fd, flags);
if (flags == -1)
return PyErr_SetFromErrno(PyExc_IOError);
return PyInt_FromLong(flags);
}
// Convert an OS file handle to a C runtime file descriptor.
static PyObject *msvcrt_open_osfhandle(PyObject *self, PyObject *args)
{
long handle;
int flags;
int fd;
if (!PyArg_ParseTuple(args, "li:open_osfhandle", &handle, &flags))
return PyErr_SetFromErrno(PyExc_IOError);
fd = _open_osfhandle(handle, flags);
if (fd == -1)
return PyErr_SetFromErrno(PyExc_IOError);
return PyInt_FromLong(fd);
}
// Convert a C runtime file descriptor to an OS file handle.
static PyObject *msvcrt_get_osfhandle(PyObject *self, PyObject *args)
{
int fd;
long handle;
if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd))
return NULL;
handle = _get_osfhandle(fd);
if (handle == -1)
return PyErr_SetFromErrno(PyExc_IOError);
return PyInt_FromLong(handle);
}
/* Console I/O */
#include <conio.h>
static PyObject *msvcrt_kbhit(PyObject *self, PyObject *args)
{
int ok;
if (!PyArg_ParseTuple(args, ":kbhit"))
return NULL;
ok = _kbhit();
return PyInt_FromLong(ok);
}
static PyObject *msvcrt_getch(PyObject *self, PyObject *args)
{
int ch;
char s[1];
if (!PyArg_ParseTuple(args, ":getch"))
return NULL;
ch = _getch();
s[0] = ch;
return PyString_FromStringAndSize(s, 1);
}
static PyObject *msvcrt_getche(PyObject *self, PyObject *args)
{
int ch;
char s[1];
if (!PyArg_ParseTuple(args, ":getche"))
return NULL;
ch = _getche();
s[0] = ch;
return PyString_FromStringAndSize(s, 1);
}
static PyObject *msvcrt_putch(PyObject *self, PyObject *args)
{
char ch;
if (!PyArg_ParseTuple(args, "c:putch", &ch))
return NULL;
_putch(ch);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *msvcrt_ungetch(PyObject *self, PyObject *args)
{
char ch;
if (!PyArg_ParseTuple(args, "c:ungetch", &ch))
return NULL;
_ungetch(ch);
Py_INCREF(Py_None);
return Py_None;
}
/* List of functions exported by this module */
static struct PyMethodDef msvcrt_functions[] = {
{"heapmin", msvcrt_heapmin, 1},
{"locking", msvcrt_locking, 1},
{"heapmin", msvcrt_heapmin, 1},
{"setmode", msvcrt_setmode, 1},
{"open_osfhandle", msvcrt_open_osfhandle, 1},
{"get_osfhandle", msvcrt_get_osfhandle, 1},
{"kbhit", msvcrt_kbhit, 1},
{"getch", msvcrt_getch, 1},
{"getche", msvcrt_getche, 1},
{"putch", msvcrt_putch, 1},
{"ungetch", msvcrt_ungetch, 1},
{NULL, NULL}
};