OSDN Git Service

libdrm: drmGetMinorNameFromFd: Fix FreeBSD variant
authorEmmanuel Vadot <manu@FreeBSD.org>
Tue, 28 Apr 2020 13:26:13 +0000 (15:26 +0200)
committerEmmanuel Vadot <manu@FreeBSD.org>
Mon, 4 May 2020 19:19:58 +0000 (21:19 +0200)
Fix the FreeBSD variant by getting the node type represented by fd to deduce
the target minor name.
We then return the full /dev/dri/<minorname><id> version.

Fix: #41
Fixes: 6818a50b12
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Signed-off-by: Emmanuel Vadot <manu@FreeBSD.org>
xf86drm.c

index 08e5caf..6fe0296 100644 (file)
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -2947,7 +2947,7 @@ static char *drmGetMinorNameForFD(int fd, int type)
     char dname[SPECNAMELEN];
     const char *mname;
     char name[SPECNAMELEN];
-    int id, maj, min;
+    int id, maj, min, nodetype, i;
 
     if (fstat(fd, &sbuf))
         return NULL;
@@ -2965,14 +2965,25 @@ static char *drmGetMinorNameForFD(int fd, int type)
      * FreeBSD on amd64/i386/powerpc external kernel modules create node in
      * in /dev/drm/ and links in /dev/dri while a WIP in kernel driver creates
      * only device nodes in /dev/dri/ */
+
+    /* Get the node type represented by fd so we can deduce the target name */
+    nodetype = drmGetMinorType(maj, min);
+    if (nodetype == -1)
+        return (NULL);
     mname = drmGetMinorName(type);
-    if (sscanf(dname, "drm/%d", &id) != 1) {
-        snprintf(name, sizeof(name), "dri/%s", mname);
-        if (strncmp(name, dname, strlen(name)) != 0)
-            return NULL;
-        snprintf(name, sizeof(name), "/dev/%s", dname);
-    } else
-        snprintf(name, sizeof(name), DRM_DIR_NAME "/%s%d", mname, id);
+
+    for (i = 0; i < SPECNAMELEN; i++) {
+        if (isalpha(dname[i]) == 0 && dname[i] != '/')
+           break;
+    }
+    if (dname[i] == '\0')
+        return (NULL);
+
+    id = (int)strtol(&dname[i], NULL, 10);
+    id -= drmGetMinorBase(nodetype);
+    snprintf(name, sizeof(name), DRM_DIR_NAME "/%s%d", mname,
+         id + drmGetMinorBase(type));
+
     return strdup(name);
 #else
     struct stat sbuf;