summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--include/drm++/drm.hpp20
-rw-r--r--include/drm++/helper/ioctl.hpp1
-rw-r--r--src/drm.cpp60
-rw-r--r--src/helper/ioctl.cpp7
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;