123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- /* 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;
- }
|