[v2 5/6] xfree86/linux: implement xf86DMIInit
Peter Hutterer
peter.hutterer at who-t.net
Tue Dec 17 18:25:50 PST 2013
On Tue, Dec 17, 2013 at 11:35:58PM +0100, Daniel Martin wrote:
> 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}
> +};
two things:
* add a comment here that all the other ones are automatically mapped
because the filename == keyname
* yikes, I had a massive doubletake on this. please split the struct up here
into:
struct foo {
};
static const struct foo bar[] = {};
much easier to comprehend.
> +
> +/*
> + * 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;
better to explicitly check for num_read > 0 than rely on xstrnrtrim to catch
that for us.
Cheers,
Peter
> +
> + 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