diff options
Diffstat (limited to '')
| -rw-r--r-- | include/drm++/drm.hpp | 20 | ||||
| -rw-r--r-- | include/drm++/helper/ioctl.hpp | 1 | ||||
| -rw-r--r-- | src/drm.cpp | 60 | ||||
| -rw-r--r-- | src/helper/ioctl.cpp | 7 |
4 files changed, 74 insertions, 14 deletions
diff --git a/include/drm++/drm.hpp b/include/drm++/drm.hpp index 2833adf..4e94010 100644 --- a/include/drm++/drm.hpp +++ b/include/drm++/drm.hpp @@ -133,6 +133,8 @@ #include "helper/macros.hpp" #include "helper/types.hpp" +#include <string> + namespace drm { /// @@ -146,6 +148,11 @@ public: /// @throws std::invalid_argument if fd is invalid Device(int fd); + /// Set the client name for this file descriptor, useful for debugging and tracking. + void setClientName(const std::string& name) const; + + /* Authentication */ + /// Attempt to acquire DRM master on the device. This will fail if another process is /// already DRM master. void acquireMaster() const; @@ -153,16 +160,23 @@ public: /// Release DRM master on the device. void releaseMaster() const; + /// Fetch the magic token. + [[nodiscard]] u32 magic() const; + /// Authenticate a file descriptor via magic token, allowing for access to /// restricted ioctls (such as mode setting). void authenticate(u32 magic) const; + /* Device information */ + + /// Get the unique string for this device. This operation is restricted to the DRM master. + [[nodiscard]] std::string unique() const; + // Private access GETTER(fd) - GETTER(magic) // Move constructor/operator - Device(Device&& other) noexcept : m_fd(other.m_fd), m_magic(other.m_magic) { + Device(Device&& other) noexcept : m_fd(other.m_fd) { other.m_fd = -1; // invalidate other } @@ -170,7 +184,6 @@ public: if (this != &other) { this->destruct(); this->m_fd = other.m_fd; - this->m_magic = other.m_magic; other.m_fd = -1; // invalidate other } @@ -187,7 +200,6 @@ public: private: int m_fd; // indicates device validity (>= 0) - u32 m_magic; void destruct() noexcept; }; diff --git a/include/drm++/helper/ioctl.hpp b/include/drm++/helper/ioctl.hpp index fe87f3c..bd6c44a 100644 --- a/include/drm++/helper/ioctl.hpp +++ b/include/drm++/helper/ioctl.hpp @@ -15,6 +15,7 @@ namespace drm::ioctl { /// Type of ioctl() error. enum class Error : u8 { BadFileDescriptor, + NoAccess, InvalidArgument, NotSupported, Other //!< Check errno field diff --git a/src/drm.cpp b/src/drm.cpp index 3046412..66fe147 100644 --- a/src/drm.cpp +++ b/src/drm.cpp @@ -7,6 +7,7 @@ #include <stdexcept> #include <drm.h> +#include <string> #include <unistd.h> using namespace drm; @@ -15,14 +16,27 @@ Device::Device(int fd) : m_fd(fd) { if (this->m_fd < 0) { throw std::invalid_argument("invalid file descriptor"); } +} - drm_auth args{ - +void Device::setClientName(const std::string& name) const { + drm_set_client_name name_args{ + .name_len = name.size(), + .name = reinterpret_cast<u64>(name.data()) }; - ioctl::perform(this->m_fd, DRM_IOCTL_GET_MAGIC, args); - this->m_magic = args.magic; + ioctl::perform(this->m_fd, DRM_IOCTL_SET_CLIENT_NAME, name_args); } +void Device::destruct() noexcept { + if (this->m_fd < 0) { + return; + } + + ::close(this->m_fd); + this->m_fd = -1; +} + +/* Authentication */ + void Device::acquireMaster() const { ioctl::perform(this->m_fd, DRM_IOCTL_SET_MASTER); } @@ -31,6 +45,14 @@ void Device::releaseMaster() const { ioctl::perform(this->m_fd, DRM_IOCTL_DROP_MASTER); } +u32 Device::magic() const { + drm_auth auth_args{ + .magic = 0 + }; + ioctl::perform(this->m_fd, DRM_IOCTL_GET_MAGIC, auth_args); + return auth_args.magic; +} + void Device::authenticate(u32 magic) const { drm_auth args{ .magic = magic @@ -38,11 +60,29 @@ void Device::authenticate(u32 magic) const { ioctl::perform(this->m_fd, DRM_IOCTL_AUTH_MAGIC, args); } -void Device::destruct() noexcept { - if (this->m_fd < 0) { - return; - } +/* Device information */ - ::close(this->m_fd); - this->m_fd = -1; +std::string Device::unique() const { + drm_set_version version_args{ + .drm_di_major = 1, + .drm_di_minor = 4, // See kernel drm_ioctl.c for why this is here + .drm_dd_major = -1, + .drm_dd_minor = -1 + }; + ioctl::perform(this->m_fd, DRM_IOCTL_SET_VERSION, version_args); + + drm_unique unique_args{ + .unique_len = 0, + }; + ioctl::perform(this->m_fd, DRM_IOCTL_GET_UNIQUE, unique_args); + + std::string unique(unique_args.unique_len, '\0'); + + unique_args = { + .unique_len = unique.size(), + .unique = unique.data() + }; + ioctl::perform(this->m_fd, DRM_IOCTL_GET_UNIQUE, unique_args); + + return unique; } diff --git a/src/helper/ioctl.cpp b/src/helper/ioctl.cpp index 21a1ccb..8889efc 100644 --- a/src/helper/ioctl.cpp +++ b/src/helper/ioctl.cpp @@ -19,6 +19,13 @@ Exception::Exception(int fd, unsigned long op) this->m_fd, this->m_op ); break; + case EACCES: + this->m_code = Error::NoAccess; + this->m_what = std::format( + "ioctl({}, 0x{:x}) failed: Permission denied", + this->m_fd, this->m_op + ); + break; case EINVAL: case ENOTTY: this->m_code = Error::InvalidArgument; |
