PageRenderTime 50ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/rlib/rdynload.py

https://bitbucket.org/pypy/pypy/
Python | 149 lines | 125 code | 18 blank | 6 comment | 11 complexity | e21ec1b94c1bb10563664a0df5161992 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. """ Various rpython-level functions for dlopen
  2. """
  3. from pypy.rpython.tool import rffi_platform
  4. from pypy.rpython.lltypesystem import rffi
  5. from pypy.rlib.rarithmetic import r_uint
  6. from pypy.translator.tool.cbuild import ExternalCompilationInfo
  7. from pypy.translator.platform import platform
  8. import sys
  9. # maaaybe isinstance here would be better. Think
  10. _MSVC = platform.name == "msvc"
  11. _MINGW = platform.name == "mingw32"
  12. _WIN32 = _MSVC or _MINGW
  13. _MAC_OS = platform.name == "darwin"
  14. _FREEBSD = sys.platform.startswith("freebsd")
  15. if _WIN32:
  16. from pypy.rlib import rwin32
  17. includes = ['windows.h']
  18. else:
  19. includes = ['dlfcn.h']
  20. if _MAC_OS:
  21. pre_include_bits = ['#define MACOSX']
  22. else:
  23. pre_include_bits = []
  24. if _FREEBSD or _WIN32:
  25. libraries = []
  26. else:
  27. libraries = ['dl']
  28. eci = ExternalCompilationInfo(
  29. pre_include_bits = pre_include_bits,
  30. includes = includes,
  31. libraries = libraries,
  32. )
  33. class CConfig:
  34. _compilation_info_ = eci
  35. RTLD_LOCAL = rffi_platform.DefinedConstantInteger('RTLD_LOCAL')
  36. RTLD_GLOBAL = rffi_platform.DefinedConstantInteger('RTLD_GLOBAL')
  37. RTLD_NOW = rffi_platform.DefinedConstantInteger('RTLD_NOW')
  38. class cConfig:
  39. pass
  40. for k, v in rffi_platform.configure(CConfig).items():
  41. setattr(cConfig, k, v)
  42. def external(name, args, result, **kwds):
  43. return rffi.llexternal(name, args, result, compilation_info=eci, **kwds)
  44. class DLOpenError(Exception):
  45. def __init__(self, msg):
  46. self.msg = msg
  47. def __str__(self):
  48. return repr(self.msg)
  49. if not _WIN32:
  50. c_dlopen = external('dlopen', [rffi.CCHARP, rffi.INT], rffi.VOIDP)
  51. c_dlclose = external('dlclose', [rffi.VOIDP], rffi.INT, threadsafe=False)
  52. c_dlerror = external('dlerror', [], rffi.CCHARP)
  53. c_dlsym = external('dlsym', [rffi.VOIDP, rffi.CCHARP], rffi.VOIDP)
  54. DLLHANDLE = rffi.VOIDP
  55. RTLD_LOCAL = cConfig.RTLD_LOCAL
  56. RTLD_GLOBAL = cConfig.RTLD_GLOBAL
  57. RTLD_NOW = cConfig.RTLD_NOW
  58. def dlerror():
  59. # XXX this would never work on top of ll2ctypes, because
  60. # ctypes are calling dlerror itself, unsure if I can do much in this
  61. # area (nor I would like to)
  62. res = c_dlerror()
  63. if not res:
  64. return ""
  65. return rffi.charp2str(res)
  66. def dlopen(name, mode=-1):
  67. """ Wrapper around C-level dlopen
  68. """
  69. if mode == -1:
  70. if RTLD_LOCAL is not None:
  71. mode = RTLD_LOCAL
  72. else:
  73. mode = 0
  74. mode |= RTLD_NOW
  75. res = c_dlopen(name, rffi.cast(rffi.INT, mode))
  76. if not res:
  77. err = dlerror()
  78. raise DLOpenError(err)
  79. return res
  80. dlclose = c_dlclose
  81. def dlsym(libhandle, name):
  82. """ Wrapper around C-level dlsym
  83. """
  84. res = c_dlsym(libhandle, name)
  85. if not res:
  86. raise KeyError(name)
  87. # XXX rffi.cast here...
  88. return res
  89. def dlsym_byordinal(handle, index):
  90. # Never called
  91. raise KeyError(index)
  92. if _WIN32:
  93. DLLHANDLE = rwin32.HMODULE
  94. def dlopen(name, mode=-1):
  95. # mode is unused on windows, but a consistant signature
  96. res = rwin32.LoadLibrary(name)
  97. if not res:
  98. err = rwin32.GetLastError()
  99. raise DLOpenError(rwin32.FormatError(err))
  100. return res
  101. def dlclose(handle):
  102. res = rwin32.FreeLibrary(handle)
  103. if res:
  104. return -1
  105. else:
  106. return 0
  107. def dlsym(handle, name):
  108. res = rwin32.GetProcAddress(handle, name)
  109. if not res:
  110. raise KeyError(name)
  111. # XXX rffi.cast here...
  112. return res
  113. def dlsym_byordinal(handle, index):
  114. # equivalent to MAKEINTRESOURCEA
  115. intresource = rffi.cast(rffi.CCHARP, r_uint(index) & 0xFFFF)
  116. res = rwin32.GetProcAddress(handle, intresource)
  117. if not res:
  118. raise KeyError(index)
  119. # XXX rffi.cast here...
  120. return res
  121. LoadLibrary = rwin32.LoadLibrary