1 /* 2 * Copyright (C) 2015-2016 Gerd Hoffmann <kraxel@redhat.com> 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 16 */ 17 #include "qemu/osdep.h" 18 #include "qemu/drm.h" 19 20 #include <glob.h> 21 #include <dirent.h> 22 23 int qemu_drm_rendernode_open(const char *rendernode) 24 { 25 DIR *dir; 26 struct dirent *e; 27 struct stat st; 28 int r, fd, ret; 29 char *p; 30 31 if (rendernode) { 32 return open(rendernode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK); 33 } 34 35 dir = opendir("/dev/dri"); 36 if (!dir) { 37 return -1; 38 } 39 40 fd = -1; 41 while ((e = readdir(dir))) { 42 if (strncmp(e->d_name, "renderD", 7)) { 43 continue; 44 } 45 46 p = g_strdup_printf("/dev/dri/%s", e->d_name); 47 48 r = open(p, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK); 49 if (r < 0) { 50 g_free(p); 51 continue; 52 } 53 54 /* 55 * prefer fstat() over checking e->d_type == DT_CHR for 56 * portability reasons 57 */ 58 ret = fstat(r, &st); 59 if (ret < 0 || (st.st_mode & S_IFMT) != S_IFCHR) { 60 close(r); 61 g_free(p); 62 continue; 63 } 64 65 fd = r; 66 g_free(p); 67 break; 68 } 69 70 closedir(dir); 71 if (fd < 0) { 72 return -1; 73 } 74 return fd; 75 } 76