intel/perf: adapt to platforms like Solaris without d_type in struct dirent
authorAlan Coopersmith <alan.coopersmith@oracle.com>
Wed, 6 Nov 2019 00:56:46 +0000 (16:56 -0800)
committerMarge Bot <eric+marge@anholt.net>
Wed, 22 Jan 2020 20:23:51 +0000 (20:23 +0000)
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
[Eric: factor out the is_dir_or_link() check and fix a bug in v1]
Signed-off-by: Eric Engestrom <eric.engestrom@intel.com>
v3: include directory path when lstat'ing files
v4: fix inverted check in enumerate_sysfs_metrics()

Reviewed-by: Eric Engestrom <eric.engestrom@intel.com>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/2258>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/2258>

meson.build
src/intel/perf/gen_perf.c

index 35cd2e6..2cf0ee7 100644 (file)
@@ -1178,6 +1178,11 @@ if host_machine.system() != 'windows'
   endif
 endif
 
+if cc.has_member('struct dirent', 'd_type', prefix: '''#include <sys/types.h>
+   #include <dirent.h>''')
+   pre_args += '-DHAVE_DIRENT_D_TYPE'
+endif
+
 # strtod locale support
 if cc.links('''
     #define _GNU_SOURCE
index 421dfb8..38dc016 100644 (file)
 #include <unistd.h>
 #include <errno.h>
 
+#ifndef HAVE_DIRENT_D_TYPE
+#include <limits.h> // PATH_MAX
+#endif
+
 #include <drm-uapi/i915_drm.h>
 
 #include "common/gen_gem.h"
@@ -396,6 +400,20 @@ static inline uint64_t to_user_pointer(void *ptr)
 }
 
 static bool
+is_dir_or_link(const struct dirent *entry, const char *parent_dir)
+{
+#ifdef HAVE_DIRENT_D_TYPE
+   return entry->d_type == DT_DIR || entry->d_type == DT_LNK;
+#else
+   struct stat st;
+   char path[PATH_MAX + 1];
+   snprintf(path, sizeof(path), "%s/%s", parent_dir, entry->d_name);
+   lstat(path, &st);
+   return S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode);
+#endif
+}
+
+static bool
 get_sysfs_dev_dir(struct gen_perf_config *perf, int fd)
 {
    struct stat sb;
@@ -434,8 +452,7 @@ get_sysfs_dev_dir(struct gen_perf_config *perf, int fd)
    }
 
    while ((drm_entry = readdir(drmdir))) {
-      if ((drm_entry->d_type == DT_DIR ||
-           drm_entry->d_type == DT_LNK) &&
+      if (is_dir_or_link(drm_entry, perf->sysfs_dev_dir) &&
           strncmp(drm_entry->d_name, "card", 4) == 0)
       {
          len = snprintf(perf->sysfs_dev_dir,
@@ -551,9 +568,7 @@ enumerate_sysfs_metrics(struct gen_perf_config *perf)
 
    while ((metric_entry = readdir(metricsdir))) {
       struct hash_entry *entry;
-
-      if ((metric_entry->d_type != DT_DIR &&
-           metric_entry->d_type != DT_LNK) ||
+      if (!is_dir_or_link(metric_entry, buf) ||
           metric_entry->d_name[0] == '.')
          continue;