From: Emil Velikov Date: Thu, 10 Nov 2016 17:26:50 +0000 (+0000) Subject: xf86drm: introduce drmGetDeviceNameFromFd2 X-Git-Tag: libdrm-2.4.74~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=37d790f7d449874d0bf199d9ca9871d12b4d599a;p=platform%2Fupstream%2Flibdrm.git xf86drm: introduce drmGetDeviceNameFromFd2 The original version considered only card devices, while this will pick the device/node name regardless - card, control, renderD, other... Current implementation is "linux" specific, in such that it relies on sysfs/uevent file. At the same time this gives us the flexibility to support any nodes even future ones, as long as they're within DRM_MAJOR. Shamelessly copied from mesa, latter by: Gary Wong Signed-off-by: Emil Velikov Reviewed-by: Nicolai Hähnle --- diff --git a/xf86drm.c b/xf86drm.c index 9b97bbb..ed924a7 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -3303,3 +3303,54 @@ free_locals: free(local_devices); return ret; } + +char *drmGetDeviceNameFromFd2(int fd) +{ +#ifdef __linux__ + struct stat sbuf; + char *device_name = NULL; + unsigned int maj, min; + FILE *f; + char buf[512]; + static const char match[9] = "\nDEVNAME="; + int expected = 1; + + + if (fstat(fd, &sbuf)) + return NULL; + + maj = major(sbuf.st_rdev); + min = minor(sbuf.st_rdev); + + if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) + return NULL; + + snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/uevent", maj, min); + if (!(f = fopen(buf, "r"))) + return NULL; + + while (expected < sizeof(match)) { + int c = getc(f); + + if (c == EOF) { + fclose(f); + return NULL; + } else if (c == match[expected] ) + expected++; + else + expected = 0; + } + + strcpy(buf, "/dev/"); + if (fgets(buf + 5, sizeof(buf) - 5, f)) { + buf[strcspn(buf, "\n")] = '\0'; + device_name = strdup(buf); + } + + fclose(f); + return device_name; +#else +#warning "Missing implementation of drmGetDeviceNameFromFd2" + return NULL; +#endif +} diff --git a/xf86drm.h b/xf86drm.h index 481d882..4da6bd3 100644 --- a/xf86drm.h +++ b/xf86drm.h @@ -753,6 +753,11 @@ typedef struct _drmEventContext { extern int drmHandleEvent(int fd, drmEventContextPtr evctx); extern char *drmGetDeviceNameFromFd(int fd); + +/* Improved version of drmGetDeviceNameFromFd which attributes for any type of + * device/node - card, control or renderD. + */ +extern char *drmGetDeviceNameFromFd2(int fd); extern int drmGetNodeTypeFromFd(int fd); extern int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd);