mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 10:26:02 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			130 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			130 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Python UUID module that wraps libuuid or Windows rpcrt4.dll.
 | |
|  * DCE compatible Universally Unique Identifier library.
 | |
|  */
 | |
| 
 | |
| #include "pyconfig.h"   // Py_GIL_DISABLED
 | |
| 
 | |
| #ifndef Py_GIL_DISABLED
 | |
| // Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED
 | |
| #define Py_LIMITED_API 0x030c0000
 | |
| #endif
 | |
| 
 | |
| #include "Python.h"
 | |
| #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>
 | |
| #endif
 | |
| 
 | |
| #ifdef MS_WINDOWS
 | |
| #include <rpc.h>
 | |
| #endif
 | |
| 
 | |
| #ifndef MS_WINDOWS
 | |
| 
 | |
| static PyObject *
 | |
| py_uuid_generate_time_safe(PyObject *Py_UNUSED(context),
 | |
|                            PyObject *Py_UNUSED(ignored))
 | |
| {
 | |
|     uuid_t uuid;
 | |
| #ifdef HAVE_UUID_GENERATE_TIME_SAFE
 | |
|     int res;
 | |
| 
 | |
|     res = uuid_generate_time_safe(uuid);
 | |
|     return Py_BuildValue("y#i", (const char *) uuid, sizeof(uuid), res);
 | |
| #elif defined(HAVE_UUID_CREATE)
 | |
|     uint32_t status;
 | |
|     uuid_create(&uuid, &status);
 | |
| # 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
 | |
|     return Py_BuildValue("y#i", (const char *) &uuid, sizeof(uuid), (int) status);
 | |
| # endif /* HAVE_UUID_CREATE */
 | |
| #else /* HAVE_UUID_GENERATE_TIME_SAFE */
 | |
|     uuid_generate_time(uuid);
 | |
|     return Py_BuildValue("y#O", (const char *) uuid, sizeof(uuid), Py_None);
 | |
| #endif /* HAVE_UUID_GENERATE_TIME_SAFE */
 | |
| }
 | |
| 
 | |
| #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 */
 | |
| 
 | |
| 
 | |
| static int
 | |
| uuid_exec(PyObject *module) {
 | |
|     assert(sizeof(uuid_t) == 16);
 | |
| #if defined(MS_WINDOWS)
 | |
|     int has_uuid_generate_time_safe = 0;
 | |
| #elif defined(HAVE_UUID_GENERATE_TIME_SAFE)
 | |
|     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;
 | |
| }
 | |
| 
 | |
| static PyMethodDef uuid_methods[] = {
 | |
| #if defined(HAVE_UUID_UUID_H) || defined(HAVE_UUID_H)
 | |
|     {"generate_time_safe", py_uuid_generate_time_safe, METH_NOARGS, NULL},
 | |
| #endif
 | |
| #if defined(MS_WINDOWS)
 | |
|     {"UuidCreate", py_UuidCreate, METH_NOARGS, NULL},
 | |
| #endif
 | |
|     {NULL, NULL, 0, NULL}           /* sentinel */
 | |
| };
 | |
| 
 | |
| static PyModuleDef_Slot uuid_slots[] = {
 | |
|     {Py_mod_exec, uuid_exec},
 | |
|     {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
 | |
|     {0, NULL}
 | |
| };
 | |
| 
 | |
| static struct PyModuleDef uuidmodule = {
 | |
|     PyModuleDef_HEAD_INIT,
 | |
|     .m_name = "_uuid",
 | |
|     .m_size = 0,
 | |
|     .m_methods = uuid_methods,
 | |
|     .m_slots = uuid_slots,
 | |
| };
 | |
| 
 | |
| PyMODINIT_FUNC
 | |
| PyInit__uuid(void)
 | |
| {
 | |
|     return PyModuleDef_Init(&uuidmodule);
 | |
| }
 | 
