[v2 5/6] xfree86/linux: implement xf86DMIInit
Daniel Martin
consume.noise at gmail.com
Tue Dec 17 14:35:58 PST 2013
Read DMI identifiers from sysfs (/sys/devices/virtual/dmi/id).
Signed-off-by: Daniel Martin <consume.noise at gmail.com>
---
v2: get_value returns a strduped string, fixed typos
hw/xfree86/os-support/linux/Makefile.am | 2 +-
hw/xfree86/os-support/linux/lnx_dmi.c | 118 ++++++++++++++++++++++++++++++++
2 files changed, 119 insertions(+), 1 deletion(-)
create mode 100644 hw/xfree86/os-support/linux/lnx_dmi.c
diff --git a/hw/xfree86/os-support/linux/Makefile.am b/hw/xfree86/os-support/linux/Makefile.am
index e1f8bd8..22c98ea 100644
--- a/hw/xfree86/os-support/linux/Makefile.am
+++ b/hw/xfree86/os-support/linux/Makefile.am
@@ -28,12 +28,12 @@ liblinux_la_SOURCES = \
../shared/posix_tty.c \
../shared/sigio.c \
../shared/vidmem.c \
- ../stub/stub_dmi.c \
$(ACPI_SRCS) \
$(APM_SRCS) \
$(PLATFORM_PCI_SUPPORT) \
lnx_agp.c \
lnx_bell.c \
+ lnx_dmi.c \
lnx_init.c \
lnx_kmod.c \
lnx_platform.c \
diff --git a/hw/xfree86/os-support/linux/lnx_dmi.c b/hw/xfree86/os-support/linux/lnx_dmi.c
new file mode 100644
index 0000000..7820a19
--- /dev/null
+++ b/hw/xfree86/os-support/linux/lnx_dmi.c
@@ -0,0 +1,118 @@
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <dirent.h>
+
+#include "parser/xf86Parser.h"
+#include "xf86.h"
+#include "xf86_OSlib.h"
+
+
+static const char SYSFS_DMI_PATH[] = "/sys/devices/virtual/dmi/id";
+
+struct dname_to_key {
+ const char *const d_name;
+ const char *const key;
+}
+/* Filename that need to be mapped to a key. */
+static const SYSFS_ENTRY_TO_KEYMAP[] = {
+ {"sys_vendor", "system_vendor"},
+ {NULL, NULL}
+};
+
+/*
+ * Get the key for a filename.
+ */
+static const char *const
+get_key(const char *const d_name)
+{
+ const struct dname_to_key *cur;
+
+ if (xf86DMIIsValidKey(d_name))
+ return d_name;
+
+ for (cur = SYSFS_ENTRY_TO_KEYMAP; cur->key; cur++)
+ if ((strcmp(cur->d_name, d_name) == 0) && xf86DMIIsValidKey(cur->key))
+ return cur->key;
+
+ return NULL;
+}
+
+/*
+ * Get the DMI id value from a file in SYSFS_DMI_PATH. Returns a
+ * zero-terminated allocated string on success, NULL otherwise.
+ */
+static char *
+get_value(const char *const d_name)
+{
+ char buf[PATH_MAX];
+ int fd;
+ size_t num_read;
+
+ snprintf(buf, sizeof(buf), "%s/%s", SYSFS_DMI_PATH, d_name);
+ fd = open(buf, O_RDONLY, 0);
+ if (fd < 0)
+ return NULL;
+
+ num_read = read(fd, buf, sizeof(buf));
+ close(fd);
+
+ if (xstrnrtrim(buf, num_read) < 1)
+ return NULL;
+
+ return strdup(buf);
+}
+
+/*
+ * Filter out uninteresting files.
+ */
+static int
+scandir_filter(const struct dirent *entry)
+{
+ /* Skip non-regular files. */
+ if (entry->d_type != DT_REG)
+ return 0;
+
+ /* Skip unsupported keys. */
+ return get_key(entry->d_name) ? 1 : 0;
+}
+
+void
+xf86DMIInit(void)
+{
+ int i, num_entries;
+ struct dirent **entries;
+
+ Bool error = FALSE;
+
+ num_entries = scandir(SYSFS_DMI_PATH, &entries,
+ scandir_filter, alphasort);
+ if (num_entries < 0) {
+ xf86Msg(X_ERROR, "DMI: Can't read identifiers: %s %s\n",
+ SYSFS_DMI_PATH, strerror(errno));
+ return;
+ }
+
+ for (i = 0; i < num_entries; i++) {
+ const char *key;
+ char *value;
+
+ key = get_key(entries[i]->d_name);
+ value = get_value(entries[i]->d_name);
+ if (!key || !value || !xf86DMIAdd(key, value)) {
+ free(value);
+ error = TRUE;
+ break;
+ }
+ }
+
+ /* always cleanup entries */
+ for (i = 0; i < num_entries; i++)
+ free(entries[i]);
+ free(entries);
+
+ if (error) {
+ xf86DMICleanup();
+ }
+}
--
1.8.5.1
More information about the xorg-devel
mailing list