You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.2 KiB
94 lines
2.2 KiB
|
|
/* Emulation of PyFile_Check() and PyFile_AsFile() for Python 3. */
|
|
|
|
static PyObject *PyIOBase_TypeObj;
|
|
|
|
static int init_file_emulator(void)
|
|
{
|
|
if (PyIOBase_TypeObj == NULL) {
|
|
PyObject *io = PyImport_ImportModule("_io");
|
|
if (io == NULL)
|
|
return -1;
|
|
PyIOBase_TypeObj = PyObject_GetAttrString(io, "_IOBase");
|
|
if (PyIOBase_TypeObj == NULL)
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
#define PyFile_Check(p) PyObject_IsInstance(p, PyIOBase_TypeObj)
|
|
|
|
|
|
static void _close_file_capsule(PyObject *ob_capsule)
|
|
{
|
|
FILE *f = (FILE *)PyCapsule_GetPointer(ob_capsule, "FILE");
|
|
if (f != NULL)
|
|
fclose(f);
|
|
}
|
|
|
|
|
|
static FILE *PyFile_AsFile(PyObject *ob_file)
|
|
{
|
|
PyObject *ob, *ob_capsule = NULL, *ob_mode = NULL;
|
|
FILE *f;
|
|
int fd;
|
|
const char *mode;
|
|
|
|
ob = PyObject_CallMethod(ob_file, "flush", NULL);
|
|
if (ob == NULL)
|
|
goto fail;
|
|
Py_DECREF(ob);
|
|
|
|
ob_capsule = PyObject_GetAttrString(ob_file, "__cffi_FILE");
|
|
if (ob_capsule == NULL) {
|
|
PyErr_Clear();
|
|
|
|
fd = PyObject_AsFileDescriptor(ob_file);
|
|
if (fd < 0)
|
|
goto fail;
|
|
|
|
ob_mode = PyObject_GetAttrString(ob_file, "mode");
|
|
if (ob_mode == NULL)
|
|
goto fail;
|
|
mode = PyText_AsUTF8(ob_mode);
|
|
if (mode == NULL)
|
|
goto fail;
|
|
|
|
fd = dup(fd);
|
|
if (fd < 0) {
|
|
PyErr_SetFromErrno(PyExc_OSError);
|
|
goto fail;
|
|
}
|
|
|
|
f = fdopen(fd, mode);
|
|
if (f == NULL) {
|
|
close(fd);
|
|
PyErr_SetFromErrno(PyExc_OSError);
|
|
goto fail;
|
|
}
|
|
setbuf(f, NULL); /* non-buffered */
|
|
Py_DECREF(ob_mode);
|
|
ob_mode = NULL;
|
|
|
|
ob_capsule = PyCapsule_New(f, "FILE", _close_file_capsule);
|
|
if (ob_capsule == NULL) {
|
|
fclose(f);
|
|
goto fail;
|
|
}
|
|
|
|
if (PyObject_SetAttrString(ob_file, "__cffi_FILE", ob_capsule) < 0)
|
|
goto fail;
|
|
}
|
|
else {
|
|
f = PyCapsule_GetPointer(ob_capsule, "FILE");
|
|
}
|
|
Py_DECREF(ob_capsule); /* assumes still at least one reference */
|
|
return f;
|
|
|
|
fail:
|
|
Py_XDECREF(ob_mode);
|
|
Py_XDECREF(ob_capsule);
|
|
return NULL;
|
|
}
|