mirror of
				https://github.com/python/cpython.git
				synced 2025-11-02 22:51:25 +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);
 | 
						|
}
 |