Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix loading of libudev #31

Merged
merged 1 commit into from
Sep 28, 2024
Merged

Fix loading of libudev #31

merged 1 commit into from
Sep 28, 2024

Conversation

git-developer
Copy link

This PR fixes how libudev is loaded.

Using ctypes.cdll.LoadLibrary

Currently, ctypes.cdll.LoadLibrary() is called using libudev.so. According to the docs, the argument must be a filename. In Debian-based distributions (Debian & Ubuntu), the package libudev1 contains a file libudev.so.1, but not libudev.so:

$ dpkg -L libudev1 | grep libudev.so
/usr/lib/x86_64-linux-gnu/libudev.so.1.7.2
/usr/lib/x86_64-linux-gnu/libudev.so.1

$ python3 -c 'import ctypes; print(ctypes.cdll.LoadLibrary("libudev.so"))'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.10/ctypes/__init__.py", line 452, in LoadLibrary
    return self._dlltype(name)
  File "/usr/lib/python3.10/ctypes/__init__.py", line 374, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: libudev.so: cannot open shared object file: No such file or directory
$ python3 -c 'import ctypes; print(ctypes.cdll.LoadLibrary("libudev.so.1"))'
<CDLL 'libudev.so.1', handle 5629e9602f30 at 0x7f882f543c10>

This is by design. The trailing .1 gives the ABI version of the library. Applications should load a library using the ABI version to avoid compatibility issues, because a change of the ABI version means a breaking change that may lead to runtime issues in the application. Thus, no symlink from libudev.so to libudev.so.1 is created on installation of the package.

The package libudev-dev contains libudev.so. As a consequence, loading of the libudev library currently only works if either the package libudev-dev is installed or a symlink is created from libudev.so to libudev.so.1.

Using ctypes.CDLL

If loading by LoadLibrary() fails, a second attempt is made using ctypes.CDLL. When this also fails, an ImportError should be thrown. This does not work currently because ctypes.CDLL always returns something that is not None.

$ python3 -c 'import ctypes.util; lib_name = ctypes.util.find_library("unknown"); print(lib_name)'
None

$ python3 -c 'import ctypes.util; lib_name = ctypes.util.find_library("unknown"); print(ctypes.CDLL(lib_name))'
<CDLL 'None', handle 7f4eb8c4d2e0 at 0x7f4eb84377c0>

Thus, the ImportError is not thrown, and the application fails later when trying to use the library.

@git-developer
Copy link
Author

Fixes a runtime error on Fedora 40

@C0rn3j C0rn3j merged commit af8a442 into C0rn3j:python3 Sep 28, 2024
1 check passed
@C0rn3j
Copy link
Owner

C0rn3j commented Sep 28, 2024

LGTM, thank you!

@git-developer git-developer deleted the fix-libudev branch September 28, 2024 11:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants