[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