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