| 
									
										
										
										
											2019-06-25 01:59:51 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2020-05-12 23:32:32 +01:00
										 |  |  |  * Python UUID module that wraps libuuid or Windows rpcrt4.dll. | 
					
						
							| 
									
										
										
										
											2019-06-25 01:59:51 +08:00
										 |  |  |  * DCE compatible Universally Unique Identifier library. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-03 08:30:55 -07:00
										 |  |  | // Need limited C API version 3.13 for Py_mod_gil
 | 
					
						
							| 
									
										
										
										
											2023-11-20 15:52:00 +02:00
										 |  |  | #include "pyconfig.h"   // Py_GIL_DISABLED
 | 
					
						
							|  |  |  | #ifndef Py_GIL_DISABLED
 | 
					
						
							| 
									
										
										
										
											2024-05-03 08:30:55 -07:00
										 |  |  | #  define Py_LIMITED_API 0x030d0000
 | 
					
						
							| 
									
										
										
										
											2023-10-30 12:06:09 -04:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2023-10-18 01:07:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-28 23:03:06 +02:00
										 |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											2021-11-24 11:20:37 +02:00
										 |  |  | #if defined(HAVE_UUID_H)
 | 
					
						
							|  |  |  |   // AIX, FreeBSD, libuuid with pkgconf
 | 
					
						
							|  |  |  |   #include <uuid.h>
 | 
					
						
							|  |  |  | #elif defined(HAVE_UUID_UUID_H)
 | 
					
						
							|  |  |  |   // libuuid without pkgconf
 | 
					
						
							|  |  |  |   #include <uuid/uuid.h>
 | 
					
						
							| 
									
										
										
										
											2017-12-30 22:39:20 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-09-28 23:03:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-12 23:32:32 +01:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  | #include <rpc.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef MS_WINDOWS
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-28 23:03:06 +02:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2018-04-30 00:29:33 +05:30
										 |  |  | py_uuid_generate_time_safe(PyObject *Py_UNUSED(context), | 
					
						
							|  |  |  |                            PyObject *Py_UNUSED(ignored)) | 
					
						
							| 
									
										
										
										
											2017-09-28 23:03:06 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-12-30 22:39:20 +01:00
										 |  |  |     uuid_t uuid; | 
					
						
							| 
									
										
										
										
											2017-11-08 23:09:16 +03:00
										 |  |  | #ifdef HAVE_UUID_GENERATE_TIME_SAFE
 | 
					
						
							| 
									
										
										
										
											2017-09-28 23:03:06 +02:00
										 |  |  |     int res; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-30 22:39:20 +01:00
										 |  |  |     res = uuid_generate_time_safe(uuid); | 
					
						
							|  |  |  |     return Py_BuildValue("y#i", (const char *) uuid, sizeof(uuid), res); | 
					
						
							| 
									
										
										
										
											2018-05-25 01:45:09 +03:00
										 |  |  | #elif defined(HAVE_UUID_CREATE)
 | 
					
						
							| 
									
										
										
										
											2018-01-09 19:38:07 +00:00
										 |  |  |     uint32_t status; | 
					
						
							| 
									
										
										
										
											2017-12-30 22:39:20 +01:00
										 |  |  |     uuid_create(&uuid, &status); | 
					
						
							| 
									
										
										
										
											2018-05-25 01:45:09 +03:00
										 |  |  | # if defined(HAVE_UUID_ENC_BE)
 | 
					
						
							|  |  |  |     unsigned char buf[sizeof(uuid)]; | 
					
						
							|  |  |  |     uuid_enc_be(buf, &uuid); | 
					
						
							|  |  |  |     return Py_BuildValue("y#i", buf, sizeof(uuid), (int) status); | 
					
						
							|  |  |  | # else
 | 
					
						
							| 
									
										
										
										
											2017-12-30 22:39:20 +01:00
										 |  |  |     return Py_BuildValue("y#i", (const char *) &uuid, sizeof(uuid), (int) status); | 
					
						
							| 
									
										
										
										
											2020-05-12 23:32:32 +01:00
										 |  |  | # endif /* HAVE_UUID_CREATE */
 | 
					
						
							|  |  |  | #else /* HAVE_UUID_GENERATE_TIME_SAFE */
 | 
					
						
							| 
									
										
										
										
											2017-12-30 22:39:20 +01:00
										 |  |  |     uuid_generate_time(uuid); | 
					
						
							|  |  |  |     return Py_BuildValue("y#O", (const char *) uuid, sizeof(uuid), Py_None); | 
					
						
							| 
									
										
										
										
											2020-05-12 23:32:32 +01:00
										 |  |  | #endif /* HAVE_UUID_GENERATE_TIME_SAFE */
 | 
					
						
							| 
									
										
										
										
											2017-09-28 23:03:06 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-12 23:32:32 +01:00
										 |  |  | #else /* MS_WINDOWS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | py_UuidCreate(PyObject *Py_UNUSED(context), | 
					
						
							|  |  |  |               PyObject *Py_UNUSED(ignored)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     UUID uuid; | 
					
						
							|  |  |  |     RPC_STATUS res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  |     res = UuidCreateSequential(&uuid); | 
					
						
							|  |  |  |     Py_END_ALLOW_THREADS | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (res) { | 
					
						
							|  |  |  |     case RPC_S_OK: | 
					
						
							|  |  |  |     case RPC_S_UUID_LOCAL_ONLY: | 
					
						
							|  |  |  |     case RPC_S_UUID_NO_ADDRESS: | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |         All success codes, but the latter two indicate that the UUID is random | 
					
						
							|  |  |  |         rather than based on the MAC address. If the OS can't figure this out, | 
					
						
							|  |  |  |         neither can we, so we'll take it anyway. | 
					
						
							|  |  |  |         */ | 
					
						
							|  |  |  |         return Py_BuildValue("y#", (const char *)&uuid, sizeof(uuid)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     PyErr_SetFromWindowsErr(res); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* MS_WINDOWS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-31 21:43:47 +09:00
										 |  |  | static int | 
					
						
							|  |  |  | uuid_exec(PyObject *module) { | 
					
						
							|  |  |  |     assert(sizeof(uuid_t) == 16); | 
					
						
							| 
									
										
										
										
											2020-05-12 23:32:32 +01:00
										 |  |  | #if defined(MS_WINDOWS)
 | 
					
						
							|  |  |  |     int has_uuid_generate_time_safe = 0; | 
					
						
							|  |  |  | #elif defined(HAVE_UUID_GENERATE_TIME_SAFE)
 | 
					
						
							| 
									
										
										
										
											2020-03-31 21:43:47 +09:00
										 |  |  |     int has_uuid_generate_time_safe = 1; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     int has_uuid_generate_time_safe = 0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     if (PyModule_AddIntConstant(module, "has_uuid_generate_time_safe", | 
					
						
							|  |  |  |                                 has_uuid_generate_time_safe) < 0) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-09-28 23:03:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyMethodDef uuid_methods[] = { | 
					
						
							| 
									
										
										
										
											2020-05-12 23:32:32 +01:00
										 |  |  | #if defined(HAVE_UUID_UUID_H) || defined(HAVE_UUID_H)
 | 
					
						
							| 
									
										
										
										
											2018-04-30 00:29:33 +05:30
										 |  |  |     {"generate_time_safe", py_uuid_generate_time_safe, METH_NOARGS, NULL}, | 
					
						
							| 
									
										
										
										
											2020-05-12 23:32:32 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #if defined(MS_WINDOWS)
 | 
					
						
							|  |  |  |     {"UuidCreate", py_UuidCreate, METH_NOARGS, NULL}, | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-09-28 23:03:06 +02:00
										 |  |  |     {NULL, NULL, 0, NULL}           /* sentinel */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-31 21:43:47 +09:00
										 |  |  | static PyModuleDef_Slot uuid_slots[] = { | 
					
						
							|  |  |  |     {Py_mod_exec, uuid_exec}, | 
					
						
							| 
									
										
										
										
											2023-05-05 15:11:27 -06:00
										 |  |  |     {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, | 
					
						
							| 
									
										
										
										
											2024-05-03 08:30:55 -07:00
										 |  |  |     {Py_mod_gil, Py_MOD_GIL_NOT_USED}, | 
					
						
							| 
									
										
										
										
											2020-03-31 21:43:47 +09:00
										 |  |  |     {0, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-28 23:03:06 +02:00
										 |  |  | static struct PyModuleDef uuidmodule = { | 
					
						
							|  |  |  |     PyModuleDef_HEAD_INIT, | 
					
						
							|  |  |  |     .m_name = "_uuid", | 
					
						
							| 
									
										
										
										
											2020-03-31 21:43:47 +09:00
										 |  |  |     .m_size = 0, | 
					
						
							| 
									
										
										
										
											2017-09-28 23:03:06 +02:00
										 |  |  |     .m_methods = uuid_methods, | 
					
						
							| 
									
										
										
										
											2020-03-31 21:43:47 +09:00
										 |  |  |     .m_slots = uuid_slots, | 
					
						
							| 
									
										
										
										
											2017-09-28 23:03:06 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyMODINIT_FUNC | 
					
						
							|  |  |  | PyInit__uuid(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-03-31 21:43:47 +09:00
										 |  |  |     return PyModuleDef_Init(&uuidmodule); | 
					
						
							| 
									
										
										
										
											2017-09-28 23:03:06 +02:00
										 |  |  | } |