capsule.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /* Wrap void * pointers to be passed between C modules */
  2. #include "Python.h"
  3. /* Internal structure of PyCapsule */
  4. typedef struct {
  5. PyObject_HEAD
  6. void *pointer;
  7. const char *name;
  8. void *context;
  9. PyCapsule_Destructor destructor;
  10. } PyCapsule;
  11. static int
  12. _is_legal_capsule(PyCapsule *capsule, const char *invalid_capsule)
  13. {
  14. if (!capsule || !PyCapsule_CheckExact(capsule) || capsule->pointer == NULL) {
  15. PyErr_SetString(PyExc_ValueError, invalid_capsule);
  16. return 0;
  17. }
  18. return 1;
  19. }
  20. #define is_legal_capsule(capsule, name) \
  21. (_is_legal_capsule(capsule, \
  22. name " called with invalid PyCapsule object"))
  23. static int
  24. name_matches(const char *name1, const char *name2) {
  25. /* if either is NULL, */
  26. if (!name1 || !name2) {
  27. /* they're only the same if they're both NULL. */
  28. return name1 == name2;
  29. }
  30. return !strcmp(name1, name2);
  31. }
  32. PyObject *
  33. PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
  34. {
  35. PyCapsule *capsule;
  36. if (!pointer) {
  37. PyErr_SetString(PyExc_ValueError, "PyCapsule_New called with null pointer");
  38. return NULL;
  39. }
  40. capsule = PyObject_New(PyCapsule, &PyCapsule_Type);
  41. if (capsule == NULL) {
  42. return NULL;
  43. }
  44. capsule->pointer = pointer;
  45. capsule->name = name;
  46. capsule->context = NULL;
  47. capsule->destructor = destructor;
  48. return (PyObject *)capsule;
  49. }
  50. int
  51. PyCapsule_IsValid(PyObject *o, const char *name)
  52. {
  53. PyCapsule *capsule = (PyCapsule *)o;
  54. return (capsule != NULL &&
  55. PyCapsule_CheckExact(capsule) &&
  56. capsule->pointer != NULL &&
  57. name_matches(capsule->name, name));
  58. }
  59. void *
  60. PyCapsule_GetPointer(PyObject *o, const char *name)
  61. {
  62. PyCapsule *capsule = (PyCapsule *)o;
  63. if (!is_legal_capsule(capsule, "PyCapsule_GetPointer")) {
  64. return NULL;
  65. }
  66. if (!name_matches(name, capsule->name)) {
  67. PyErr_SetString(PyExc_ValueError, "PyCapsule_GetPointer called with incorrect name");
  68. return NULL;
  69. }
  70. return capsule->pointer;
  71. }
  72. const char *
  73. PyCapsule_GetName(PyObject *o)
  74. {
  75. PyCapsule *capsule = (PyCapsule *)o;
  76. if (!is_legal_capsule(capsule, "PyCapsule_GetName")) {
  77. return NULL;
  78. }
  79. return capsule->name;
  80. }
  81. PyCapsule_Destructor
  82. PyCapsule_GetDestructor(PyObject *o)
  83. {
  84. PyCapsule *capsule = (PyCapsule *)o;
  85. if (!is_legal_capsule(capsule, "PyCapsule_GetDestructor")) {
  86. return NULL;
  87. }
  88. return capsule->destructor;
  89. }
  90. void *
  91. PyCapsule_GetContext(PyObject *o)
  92. {
  93. PyCapsule *capsule = (PyCapsule *)o;
  94. if (!is_legal_capsule(capsule, "PyCapsule_GetContext")) {
  95. return NULL;
  96. }
  97. return capsule->context;
  98. }
  99. int
  100. PyCapsule_SetPointer(PyObject *o, void *pointer)
  101. {
  102. PyCapsule *capsule = (PyCapsule *)o;
  103. if (!pointer) {
  104. PyErr_SetString(PyExc_ValueError, "PyCapsule_SetPointer called with null pointer");
  105. return -1;
  106. }
  107. if (!is_legal_capsule(capsule, "PyCapsule_SetPointer")) {
  108. return -1;
  109. }
  110. capsule->pointer = pointer;
  111. return 0;
  112. }
  113. int
  114. PyCapsule_SetName(PyObject *o, const char *name)
  115. {
  116. PyCapsule *capsule = (PyCapsule *)o;
  117. if (!is_legal_capsule(capsule, "PyCapsule_SetName")) {
  118. return -1;
  119. }
  120. capsule->name = name;
  121. return 0;
  122. }
  123. int
  124. PyCapsule_SetDestructor(PyObject *o, PyCapsule_Destructor destructor)
  125. {
  126. PyCapsule *capsule = (PyCapsule *)o;
  127. if (!is_legal_capsule(capsule, "PyCapsule_SetDestructor")) {
  128. return -1;
  129. }
  130. capsule->destructor = destructor;
  131. return 0;
  132. }
  133. int
  134. PyCapsule_SetContext(PyObject *o, void *context)
  135. {
  136. PyCapsule *capsule = (PyCapsule *)o;
  137. if (!is_legal_capsule(capsule, "PyCapsule_SetContext")) {
  138. return -1;
  139. }
  140. capsule->context = context;
  141. return 0;
  142. }
  143. void *
  144. PyCapsule_Import(const char *name, int no_block)
  145. {
  146. PyObject *object = NULL;
  147. void *return_value = NULL;
  148. char *trace;
  149. #if defined(__has_feature)
  150. # if __has_feature(memory_sanitizer)
  151. __msan_unpoison_string(name);
  152. # endif
  153. #endif
  154. size_t name_length = (strlen(name) + 1) * sizeof(char);
  155. char *name_dup = (char *)PyMem_Malloc(name_length);
  156. if (!name_dup) {
  157. return PyErr_NoMemory();
  158. }
  159. memcpy(name_dup, name, name_length);
  160. trace = name_dup;
  161. while (trace) {
  162. char *dot = strchr(trace, '.');
  163. if (dot) {
  164. *dot++ = '\0';
  165. }
  166. if (object == NULL) {
  167. object = PyImport_ImportModule(trace);
  168. if (!object) {
  169. PyErr_Format(PyExc_ImportError, "PyCapsule_Import could not import module \"%s\"", trace);
  170. }
  171. } else {
  172. PyObject *object2 = PyObject_GetAttrString(object, trace);
  173. Py_SETREF(object, object2);
  174. }
  175. if (!object) {
  176. goto EXIT;
  177. }
  178. trace = dot;
  179. }
  180. /* compare attribute name to module.name by hand */
  181. if (PyCapsule_IsValid(object, name)) {
  182. PyCapsule *capsule = (PyCapsule *)object;
  183. return_value = capsule->pointer;
  184. } else {
  185. PyErr_Format(PyExc_AttributeError,
  186. "PyCapsule_Import \"%s\" is not valid",
  187. name);
  188. }
  189. EXIT:
  190. Py_XDECREF(object);
  191. if (name_dup) {
  192. PyMem_Free(name_dup);
  193. }
  194. return return_value;
  195. }
  196. static void
  197. capsule_dealloc(PyObject *o)
  198. {
  199. PyCapsule *capsule = (PyCapsule *)o;
  200. if (capsule->destructor) {
  201. capsule->destructor(o);
  202. }
  203. PyObject_Free(o);
  204. }
  205. static PyObject *
  206. capsule_repr(PyObject *o)
  207. {
  208. PyCapsule *capsule = (PyCapsule *)o;
  209. const char *name;
  210. const char *quote;
  211. if (capsule->name) {
  212. quote = "\"";
  213. name = capsule->name;
  214. } else {
  215. quote = "";
  216. name = "NULL";
  217. }
  218. return PyUnicode_FromFormat("<capsule object %s%s%s at %p>",
  219. quote, name, quote, capsule);
  220. }
  221. PyDoc_STRVAR(PyCapsule_Type__doc__,
  222. "Capsule objects let you wrap a C \"void *\" pointer in a Python\n\
  223. object. They're a way of passing data through the Python interpreter\n\
  224. without creating your own custom type.\n\
  225. \n\
  226. Capsules are used for communication between extension modules.\n\
  227. They provide a way for an extension module to export a C interface\n\
  228. to other extension modules, so that extension modules can use the\n\
  229. Python import mechanism to link to one another.\n\
  230. ");
  231. PyTypeObject PyCapsule_Type = {
  232. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  233. "PyCapsule", /*tp_name*/
  234. sizeof(PyCapsule), /*tp_basicsize*/
  235. 0, /*tp_itemsize*/
  236. /* methods */
  237. capsule_dealloc, /*tp_dealloc*/
  238. 0, /*tp_vectorcall_offset*/
  239. 0, /*tp_getattr*/
  240. 0, /*tp_setattr*/
  241. 0, /*tp_as_async*/
  242. capsule_repr, /*tp_repr*/
  243. 0, /*tp_as_number*/
  244. 0, /*tp_as_sequence*/
  245. 0, /*tp_as_mapping*/
  246. 0, /*tp_hash*/
  247. 0, /*tp_call*/
  248. 0, /*tp_str*/
  249. 0, /*tp_getattro*/
  250. 0, /*tp_setattro*/
  251. 0, /*tp_as_buffer*/
  252. 0, /*tp_flags*/
  253. PyCapsule_Type__doc__ /*tp_doc*/
  254. };