1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
/* Emulation of PyFile_Check() and PyFile_AsFile() for Python 3. */
static PyObject *PyIOBase_TypeObj;
static int init_file_emulator(void)
{
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 = NULL;
int fd;
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;
}
return PyCapsule_GetPointer(ob_capsule, "FILE");
fail:
Py_XDECREF(ob_mode);
Py_XDECREF(ob_capsule);
return NULL;
}
|