1 /* Wrap void * pointers to be passed between C modules */
2
3 #include "Python.h"
4 #include "pycore_capsule.h" // export _PyCapsule_SetTraverse()
5 #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
6 #include "pycore_object.h" // _PyObject_GC_TRACK()
7
8
9 /* Internal structure of PyCapsule */
10 typedef struct {
11 PyObject_HEAD
12 void *pointer;
13 const char *name;
14 void *context;
15 PyCapsule_Destructor destructor;
16 traverseproc traverse_func;
17 inquiry clear_func;
18 } PyCapsule;
19
20
21
22 static int
_is_legal_capsule(PyObject * op,const char * invalid_capsule)23 _is_legal_capsule(PyObject *op, const char *invalid_capsule)
24 {
25 if (!op || !PyCapsule_CheckExact(op)) {
26 goto error;
27 }
28 PyCapsule *capsule = (PyCapsule *)op;
29
30 if (capsule->pointer == NULL) {
31 goto error;
32 }
33 return 1;
34
35 error:
36 PyErr_SetString(PyExc_ValueError, invalid_capsule);
37 return 0;
38 }
39
40 #define is_legal_capsule(capsule, name) \
41 (_is_legal_capsule(capsule, \
42 name " called with invalid PyCapsule object"))
43
44
45 static int
name_matches(const char * name1,const char * name2)46 name_matches(const char *name1, const char *name2) {
47 /* if either is NULL, */
48 if (!name1 || !name2) {
49 /* they're only the same if they're both NULL. */
50 return name1 == name2;
51 }
52 return !strcmp(name1, name2);
53 }
54
55
56
57 PyObject *
PyCapsule_New(void * pointer,const char * name,PyCapsule_Destructor destructor)58 PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
59 {
60 PyCapsule *capsule;
61
62 if (!pointer) {
63 PyErr_SetString(PyExc_ValueError, "PyCapsule_New called with null pointer");
64 return NULL;
65 }
66
67 capsule = PyObject_GC_New(PyCapsule, &PyCapsule_Type);
68 if (capsule == NULL) {
69 return NULL;
70 }
71
72 capsule->pointer = pointer;
73 capsule->name = name;
74 capsule->context = NULL;
75 capsule->destructor = destructor;
76 capsule->traverse_func = NULL;
77 capsule->clear_func = NULL;
78 // Only track the object by the GC when _PyCapsule_SetTraverse() is called
79
80 return (PyObject *)capsule;
81 }
82
83
84 int
PyCapsule_IsValid(PyObject * op,const char * name)85 PyCapsule_IsValid(PyObject *op, const char *name)
86 {
87 PyCapsule *capsule = (PyCapsule *)op;
88
89 return (capsule != NULL &&
90 PyCapsule_CheckExact(capsule) &&
91 capsule->pointer != NULL &&
92 name_matches(capsule->name, name));
93 }
94
95
96 void *
PyCapsule_GetPointer(PyObject * op,const char * name)97 PyCapsule_GetPointer(PyObject *op, const char *name)
98 {
99 if (!is_legal_capsule(op, "PyCapsule_GetPointer")) {
100 return NULL;
101 }
102 PyCapsule *capsule = (PyCapsule *)op;
103
104 if (!name_matches(name, capsule->name)) {
105 PyErr_SetString(PyExc_ValueError, "PyCapsule_GetPointer called with incorrect name");
106 return NULL;
107 }
108
109 return capsule->pointer;
110 }
111
112
113 const char *
PyCapsule_GetName(PyObject * op)114 PyCapsule_GetName(PyObject *op)
115 {
116 if (!is_legal_capsule(op, "PyCapsule_GetName")) {
117 return NULL;
118 }
119 PyCapsule *capsule = (PyCapsule *)op;
120 return capsule->name;
121 }
122
123
124 PyCapsule_Destructor
PyCapsule_GetDestructor(PyObject * op)125 PyCapsule_GetDestructor(PyObject *op)
126 {
127 if (!is_legal_capsule(op, "PyCapsule_GetDestructor")) {
128 return NULL;
129 }
130 PyCapsule *capsule = (PyCapsule *)op;
131 return capsule->destructor;
132 }
133
134
135 void *
PyCapsule_GetContext(PyObject * op)136 PyCapsule_GetContext(PyObject *op)
137 {
138 if (!is_legal_capsule(op, "PyCapsule_GetContext")) {
139 return NULL;
140 }
141 PyCapsule *capsule = (PyCapsule *)op;
142 return capsule->context;
143 }
144
145
146 int
PyCapsule_SetPointer(PyObject * op,void * pointer)147 PyCapsule_SetPointer(PyObject *op, void *pointer)
148 {
149 if (!is_legal_capsule(op, "PyCapsule_SetPointer")) {
150 return -1;
151 }
152 PyCapsule *capsule = (PyCapsule *)op;
153
154 if (!pointer) {
155 PyErr_SetString(PyExc_ValueError, "PyCapsule_SetPointer called with null pointer");
156 return -1;
157 }
158
159 capsule->pointer = pointer;
160 return 0;
161 }
162
163
164 int
PyCapsule_SetName(PyObject * op,const char * name)165 PyCapsule_SetName(PyObject *op, const char *name)
166 {
167 if (!is_legal_capsule(op, "PyCapsule_SetName")) {
168 return -1;
169 }
170 PyCapsule *capsule = (PyCapsule *)op;
171
172 capsule->name = name;
173 return 0;
174 }
175
176
177 int
PyCapsule_SetDestructor(PyObject * op,PyCapsule_Destructor destructor)178 PyCapsule_SetDestructor(PyObject *op, PyCapsule_Destructor destructor)
179 {
180 if (!is_legal_capsule(op, "PyCapsule_SetDestructor")) {
181 return -1;
182 }
183 PyCapsule *capsule = (PyCapsule *)op;
184
185 capsule->destructor = destructor;
186 return 0;
187 }
188
189
190 int
PyCapsule_SetContext(PyObject * op,void * context)191 PyCapsule_SetContext(PyObject *op, void *context)
192 {
193 if (!is_legal_capsule(op, "PyCapsule_SetContext")) {
194 return -1;
195 }
196 PyCapsule *capsule = (PyCapsule *)op;
197
198 capsule->context = context;
199 return 0;
200 }
201
202
203 int
_PyCapsule_SetTraverse(PyObject * op,traverseproc traverse_func,inquiry clear_func)204 _PyCapsule_SetTraverse(PyObject *op, traverseproc traverse_func, inquiry clear_func)
205 {
206 if (!is_legal_capsule(op, "_PyCapsule_SetTraverse")) {
207 return -1;
208 }
209 PyCapsule *capsule = (PyCapsule *)op;
210
211 if (traverse_func == NULL || clear_func == NULL) {
212 PyErr_SetString(PyExc_ValueError,
213 "_PyCapsule_SetTraverse() called with NULL callback");
214 return -1;
215 }
216
217 if (!_PyObject_GC_IS_TRACKED(op)) {
218 _PyObject_GC_TRACK(op);
219 }
220
221 capsule->traverse_func = traverse_func;
222 capsule->clear_func = clear_func;
223 return 0;
224 }
225
226
227 void *
PyCapsule_Import(const char * name,int no_block)228 PyCapsule_Import(const char *name, int no_block)
229 {
230 PyObject *object = NULL;
231 void *return_value = NULL;
232 char *trace;
233 size_t name_length = (strlen(name) + 1) * sizeof(char);
234 char *name_dup = (char *)PyMem_Malloc(name_length);
235
236 if (!name_dup) {
237 return PyErr_NoMemory();
238 }
239
240 memcpy(name_dup, name, name_length);
241
242 trace = name_dup;
243 while (trace) {
244 char *dot = strchr(trace, '.');
245 if (dot) {
246 *dot++ = '\0';
247 }
248
249 if (object == NULL) {
250 object = PyImport_ImportModule(trace);
251 if (!object) {
252 PyErr_Format(PyExc_ImportError, "PyCapsule_Import could not import module \"%s\"", trace);
253 }
254 } else {
255 PyObject *object2 = PyObject_GetAttrString(object, trace);
256 Py_SETREF(object, object2);
257 }
258 if (!object) {
259 goto EXIT;
260 }
261
262 trace = dot;
263 }
264
265 /* compare attribute name to module.name by hand */
266 if (PyCapsule_IsValid(object, name)) {
267 PyCapsule *capsule = (PyCapsule *)object;
268 return_value = capsule->pointer;
269 } else {
270 PyErr_Format(PyExc_AttributeError,
271 "PyCapsule_Import \"%s\" is not valid",
272 name);
273 }
274
275 EXIT:
276 Py_XDECREF(object);
277 if (name_dup) {
278 PyMem_Free(name_dup);
279 }
280 return return_value;
281 }
282
283
284 static void
capsule_dealloc(PyObject * op)285 capsule_dealloc(PyObject *op)
286 {
287 PyCapsule *capsule = (PyCapsule *)op;
288 PyObject_GC_UnTrack(op);
289 if (capsule->destructor) {
290 capsule->destructor(op);
291 }
292 PyObject_GC_Del(op);
293 }
294
295
296 static PyObject *
capsule_repr(PyObject * o)297 capsule_repr(PyObject *o)
298 {
299 PyCapsule *capsule = (PyCapsule *)o;
300 const char *name;
301 const char *quote;
302
303 if (capsule->name) {
304 quote = "\"";
305 name = capsule->name;
306 } else {
307 quote = "";
308 name = "NULL";
309 }
310
311 return PyUnicode_FromFormat("<capsule object %s%s%s at %p>",
312 quote, name, quote, capsule);
313 }
314
315
316 static int
capsule_traverse(PyCapsule * capsule,visitproc visit,void * arg)317 capsule_traverse(PyCapsule *capsule, visitproc visit, void *arg)
318 {
319 // Capsule object is only tracked by the GC
320 // if _PyCapsule_SetTraverse() is called, but
321 // this can still be manually triggered by gc.get_referents()
322
323 if (capsule->traverse_func != NULL) {
324 return capsule->traverse_func((PyObject*)capsule, visit, arg);
325 }
326
327 return 0;
328 }
329
330
331 static int
capsule_clear(PyCapsule * capsule)332 capsule_clear(PyCapsule *capsule)
333 {
334 // Capsule object is only tracked by the GC
335 // if _PyCapsule_SetTraverse() is called
336 assert(capsule->clear_func != NULL);
337
338 return capsule->clear_func((PyObject*)capsule);
339 }
340
341
342 PyDoc_STRVAR(PyCapsule_Type__doc__,
343 "Capsule objects let you wrap a C \"void *\" pointer in a Python\n\
344 object. They're a way of passing data through the Python interpreter\n\
345 without creating your own custom type.\n\
346 \n\
347 Capsules are used for communication between extension modules.\n\
348 They provide a way for an extension module to export a C interface\n\
349 to other extension modules, so that extension modules can use the\n\
350 Python import mechanism to link to one another.\n\
351 ");
352
353 PyTypeObject PyCapsule_Type = {
354 PyVarObject_HEAD_INIT(&PyType_Type, 0)
355 .tp_name = "PyCapsule",
356 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
357 .tp_basicsize = sizeof(PyCapsule),
358 .tp_dealloc = capsule_dealloc,
359 .tp_repr = capsule_repr,
360 .tp_doc = PyCapsule_Type__doc__,
361 .tp_traverse = (traverseproc)capsule_traverse,
362 .tp_clear = (inquiry)capsule_clear,
363 };
364
365
366