(root)/
Python-3.12.0/
Modules/
_uuidmodule.c
       1  /*
       2   * Python UUID module that wraps libuuid or Windows rpcrt4.dll.
       3   * DCE compatible Universally Unique Identifier library.
       4   */
       5  
       6  #define PY_SSIZE_T_CLEAN
       7  
       8  #include "Python.h"
       9  #if defined(HAVE_UUID_H)
      10    // AIX, FreeBSD, libuuid with pkgconf
      11    #include <uuid.h>
      12  #elif defined(HAVE_UUID_UUID_H)
      13    // libuuid without pkgconf
      14    #include <uuid/uuid.h>
      15  #endif
      16  
      17  #ifdef MS_WINDOWS
      18  #include <rpc.h>
      19  #endif
      20  
      21  #ifndef MS_WINDOWS
      22  
      23  static PyObject *
      24  py_uuid_generate_time_safe(PyObject *Py_UNUSED(context),
      25                             PyObject *Py_UNUSED(ignored))
      26  {
      27      uuid_t uuid;
      28  #ifdef HAVE_UUID_GENERATE_TIME_SAFE
      29      int res;
      30  
      31      res = uuid_generate_time_safe(uuid);
      32      return Py_BuildValue("y#i", (const char *) uuid, sizeof(uuid), res);
      33  #elif defined(HAVE_UUID_CREATE)
      34      uint32_t status;
      35      uuid_create(&uuid, &status);
      36  # if defined(HAVE_UUID_ENC_BE)
      37      unsigned char buf[sizeof(uuid)];
      38      uuid_enc_be(buf, &uuid);
      39      return Py_BuildValue("y#i", buf, sizeof(uuid), (int) status);
      40  # else
      41      return Py_BuildValue("y#i", (const char *) &uuid, sizeof(uuid), (int) status);
      42  # endif /* HAVE_UUID_CREATE */
      43  #else /* HAVE_UUID_GENERATE_TIME_SAFE */
      44      uuid_generate_time(uuid);
      45      return Py_BuildValue("y#O", (const char *) uuid, sizeof(uuid), Py_None);
      46  #endif /* HAVE_UUID_GENERATE_TIME_SAFE */
      47  }
      48  
      49  #else /* MS_WINDOWS */
      50  
      51  static PyObject *
      52  py_UuidCreate(PyObject *Py_UNUSED(context),
      53                PyObject *Py_UNUSED(ignored))
      54  {
      55      UUID uuid;
      56      RPC_STATUS res;
      57  
      58      Py_BEGIN_ALLOW_THREADS
      59      res = UuidCreateSequential(&uuid);
      60      Py_END_ALLOW_THREADS
      61  
      62      switch (res) {
      63      case RPC_S_OK:
      64      case RPC_S_UUID_LOCAL_ONLY:
      65      case RPC_S_UUID_NO_ADDRESS:
      66          /*
      67          All success codes, but the latter two indicate that the UUID is random
      68          rather than based on the MAC address. If the OS can't figure this out,
      69          neither can we, so we'll take it anyway.
      70          */
      71          return Py_BuildValue("y#", (const char *)&uuid, sizeof(uuid));
      72      }
      73      PyErr_SetFromWindowsErr(res);
      74      return NULL;
      75  }
      76  
      77  #endif /* MS_WINDOWS */
      78  
      79  
      80  static int
      81  uuid_exec(PyObject *module) {
      82      assert(sizeof(uuid_t) == 16);
      83  #if defined(MS_WINDOWS)
      84      int has_uuid_generate_time_safe = 0;
      85  #elif defined(HAVE_UUID_GENERATE_TIME_SAFE)
      86      int has_uuid_generate_time_safe = 1;
      87  #else
      88      int has_uuid_generate_time_safe = 0;
      89  #endif
      90      if (PyModule_AddIntConstant(module, "has_uuid_generate_time_safe",
      91                                  has_uuid_generate_time_safe) < 0) {
      92          return -1;
      93      }
      94      return 0;
      95  }
      96  
      97  static PyMethodDef uuid_methods[] = {
      98  #if defined(HAVE_UUID_UUID_H) || defined(HAVE_UUID_H)
      99      {"generate_time_safe", py_uuid_generate_time_safe, METH_NOARGS, NULL},
     100  #endif
     101  #if defined(MS_WINDOWS)
     102      {"UuidCreate", py_UuidCreate, METH_NOARGS, NULL},
     103  #endif
     104      {NULL, NULL, 0, NULL}           /* sentinel */
     105  };
     106  
     107  static PyModuleDef_Slot uuid_slots[] = {
     108      {Py_mod_exec, uuid_exec},
     109      {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
     110      {0, NULL}
     111  };
     112  
     113  static struct PyModuleDef uuidmodule = {
     114      PyModuleDef_HEAD_INIT,
     115      .m_name = "_uuid",
     116      .m_size = 0,
     117      .m_methods = uuid_methods,
     118      .m_slots = uuid_slots,
     119  };
     120  
     121  PyMODINIT_FUNC
     122  PyInit__uuid(void)
     123  {
     124      return PyModuleDef_Init(&uuidmodule);
     125  }