2019-06-24 19:59:51 +02:00
|
|
|
/*
|
2020-05-13 00:32:32 +02:00
|
|
|
* Python UUID module that wraps libuuid or Windows rpcrt4.dll.
|
2019-06-24 19:59:51 +02:00
|
|
|
* DCE compatible Universally Unique Identifier library.
|
|
|
|
*/
|
|
|
|
|
2024-05-03 17:30:55 +02:00
|
|
|
// Need limited C API version 3.13 for Py_mod_gil
|
2023-11-20 14:52:00 +01:00
|
|
|
#include "pyconfig.h" // Py_GIL_DISABLED
|
|
|
|
#ifndef Py_GIL_DISABLED
|
2024-05-03 17:30:55 +02:00
|
|
|
# define Py_LIMITED_API 0x030d0000
|
2023-10-30 17:06:09 +01:00
|
|
|
#endif
|
2023-10-18 01:07:12 +02:00
|
|
|
|
2017-09-28 23:03:06 +02:00
|
|
|
#include "Python.h"
|
2021-11-24 10:20:37 +01: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-13 00:32:32 +02:00
|
|
|
#ifdef MS_WINDOWS
|
|
|
|
#include <rpc.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MS_WINDOWS
|
|
|
|
|
2017-09-28 23:03:06 +02:00
|
|
|
static PyObject *
|
2018-04-29 20:59:33 +02:00
|
|
|
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 21:09:16 +01: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 00:45:09 +02:00
|
|
|
#elif defined(HAVE_UUID_CREATE)
|
2018-01-09 20:38:07 +01:00
|
|
|
uint32_t status;
|
2017-12-30 22:39:20 +01:00
|
|
|
uuid_create(&uuid, &status);
|
2018-05-25 00:45:09 +02: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-13 00:32:32 +02: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-13 00:32:32 +02:00
|
|
|
#endif /* HAVE_UUID_GENERATE_TIME_SAFE */
|
2017-09-28 23:03:06 +02:00
|
|
|
}
|
|
|
|
|
2020-05-13 00:32:32 +02: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 14:43:47 +02:00
|
|
|
static int
|
|
|
|
uuid_exec(PyObject *module) {
|
|
|
|
assert(sizeof(uuid_t) == 16);
|
2020-05-13 00:32:32 +02:00
|
|
|
#if defined(MS_WINDOWS)
|
|
|
|
int has_uuid_generate_time_safe = 0;
|
|
|
|
#elif defined(HAVE_UUID_GENERATE_TIME_SAFE)
|
2020-03-31 14:43:47 +02: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-13 00:32:32 +02:00
|
|
|
#if defined(HAVE_UUID_UUID_H) || defined(HAVE_UUID_H)
|
2018-04-29 20:59:33 +02:00
|
|
|
{"generate_time_safe", py_uuid_generate_time_safe, METH_NOARGS, NULL},
|
2020-05-13 00:32:32 +02: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 14:43:47 +02:00
|
|
|
static PyModuleDef_Slot uuid_slots[] = {
|
|
|
|
{Py_mod_exec, uuid_exec},
|
2023-05-05 23:11:27 +02:00
|
|
|
{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
|
2024-05-03 17:30:55 +02:00
|
|
|
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
|
2020-03-31 14:43:47 +02:00
|
|
|
{0, NULL}
|
|
|
|
};
|
|
|
|
|
2017-09-28 23:03:06 +02:00
|
|
|
static struct PyModuleDef uuidmodule = {
|
|
|
|
PyModuleDef_HEAD_INIT,
|
|
|
|
.m_name = "_uuid",
|
2020-03-31 14:43:47 +02:00
|
|
|
.m_size = 0,
|
2017-09-28 23:03:06 +02:00
|
|
|
.m_methods = uuid_methods,
|
2020-03-31 14:43:47 +02:00
|
|
|
.m_slots = uuid_slots,
|
2017-09-28 23:03:06 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
PyMODINIT_FUNC
|
|
|
|
PyInit__uuid(void)
|
|
|
|
{
|
2020-03-31 14:43:47 +02:00
|
|
|
return PyModuleDef_Init(&uuidmodule);
|
2017-09-28 23:03:06 +02:00
|
|
|
}
|